使用ctrl + c停止python

问题:使用ctrl + c停止python

我有一个使用线程并发出大量HTTP请求的python脚本。我认为正在发生的事情是,在读取HTTP请求(使用urllib2)时,它正在阻塞并且没有响应CtrlC以停止程序。有没有办法解决?

I have a python script that uses threads and makes lots of HTTP requests. I think what’s happening is that while a HTTP request (using urllib2) is reading, it’s blocking and not responding to CtrlC to stop the program. Is there any way around this?


回答 0

在Windows上,唯一确定的方法是使用CtrlBreak。立即停止每个python脚本!

(请注意,在某些键盘上,“中断”被标记为“暂停”。)

On Windows, the only sure way is to use CtrlBreak. Stops every python script instantly!

(Note that on some keyboards, “Break” is labeled as “Pause”.)


回答 1

在python程序运行时按Ctrl+ c将导致python引发KeyboardInterrupt异常。发出大量HTTP请求的程序可能会有大量异常处理代码。如果- 块的except一部分没有指定应捕获的异常,它将捕获所有异常,包括刚刚引起的异常。正确编码的python程序将利用python异常层次结构,并且仅捕获从派生的异常。tryexceptKeyboardInterruptException

#This is the wrong way to do things
try:
  #Some stuff might raise an IO exception
except:
  #Code that ignores errors

#This is the right way to do things
try:
  #Some stuff might raise an IO exception
except Exception:
  #This won't catch KeyboardInterrupt

如果您无法更改代码(或需要终止程序以使更改生效),则可以尝试快速按Ctrl+ c。第一个KeyboardInterrupt异常会将您的程序从try块中删除,而希望KeyboardInterrupt在程序位于try块外时引发稍后的异常之一。

Pressing Ctrl + c while a python program is running will cause python to raise a KeyboardInterrupt exception. It’s likely that a program that makes lots of HTTP requests will have lots of exception handling code. If the except part of the tryexcept block doesn’t specify which exceptions it should catch, it will catch all exceptions including the KeyboardInterrupt that you just caused. A properly coded python program will make use of the python exception hierarchy and only catch exceptions that are derived from Exception.

#This is the wrong way to do things
try:
  #Some stuff might raise an IO exception
except:
  #Code that ignores errors

#This is the right way to do things
try:
  #Some stuff might raise an IO exception
except Exception:
  #This won't catch KeyboardInterrupt

If you can’t change the code (or need to kill the program so that your changes will take effect) then you can try pressing Ctrl + c rapidly. The first of the KeyboardInterrupt exceptions will knock your program out of the try block and hopefully one of the later KeyboardInterrupt exceptions will be raised when the program is outside of a try block.


回答 2

如果它在Python shell中运行,请使用Ctrl+ Z,否则找到python进程并终止它。

If it is running in the Python shell use Ctrl + Z, otherwise locate the python process and kill it.


回答 3

中断过程取决于硬件和操作系统。因此,根据运行python脚本的位置,您将具有截然不同的行为。例如,在Windows计算机上,我们有Ctrl+ CSIGINT)和Ctrl+ BreakSIGBREAK)。

因此,尽管SIGINT存在于所有系统上并且可以处理和捕获,但是SIGBREAK信号是Windows特定的(可以在CONFIG.SYS中禁用),并且实际上由BIOS作为中断向量INT 1Bh进行处理,这就是此键的原因比其他任何功能都强大。因此,如果您使用某些* nix风格的OS,则根据实现的不同,您将获得不同的结果,因为该信号不存在,而其他则存在。在Linux中,您可以通过以下方法检查可用的信号:

$ kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGEMT       8) SIGFPE       9) SIGKILL     10) SIGBUS
11) SIGSEGV     12) SIGSYS      13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGURG      17) SIGSTOP     18) SIGTSTP     19) SIGCONT     20) SIGCHLD
21) SIGTTIN     22) SIGTTOU     23) SIGIO       24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGPWR      30) SIGUSR1
31) SIGUSR2     32) SIGRTMAX

因此,如果要在Linux系统上捕获CTRL+BREAK 信号,则必须检查它们已映射了哪个POSIX信号。流行的映射有:

CTRL+\     = SIGQUIT 
CTRL+D     = SIGQUIT
CTRL+C     = SIGINT
CTRL+Z     = SIGTSTOP 
CTRL+BREAK = SIGKILL or SIGTERM or SIGSTOP

实际上,Linux下还有更多功能可用,其中SysRq(系统请求)键可以保留自己的生命

The interrupt process is hardware and OS dependent. So you will have very different behavior depending on where you run your python script. For example, on Windows machines we have Ctrl+C (SIGINT) and Ctrl+Break (SIGBREAK).

So while SIGINT is present on all systems and can be handled and caught, the SIGBREAK signal is Windows specific (and can be disabled in CONFIG.SYS) and is really handled by the BIOS as an interrupt vector INT 1Bh, which is why this key is much more powerful than any other. So if you’re using some *nix flavored OS, you will get different results depending on the implementation, since that signal is not present there, but others are. In Linux you can check what signals are available to you by:

$ kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGEMT       8) SIGFPE       9) SIGKILL     10) SIGBUS
11) SIGSEGV     12) SIGSYS      13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGURG      17) SIGSTOP     18) SIGTSTP     19) SIGCONT     20) SIGCHLD
21) SIGTTIN     22) SIGTTOU     23) SIGIO       24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGPWR      30) SIGUSR1
31) SIGUSR2     32) SIGRTMAX

So if you want to catch the CTRL+BREAK signal on a linux system you’ll have to check to what POSIX signal they have mapped that key. Popular mappings are:

CTRL+\     = SIGQUIT 
CTRL+D     = SIGQUIT
CTRL+C     = SIGINT
CTRL+Z     = SIGTSTOP 
CTRL+BREAK = SIGKILL or SIGTERM or SIGSTOP

In fact, many more functions are available under Linux, where the SysRq (System Request) key can take on a life of its own


回答 4

这篇文章很老,但是我最近遇到了同样的问题,即Ctrl+ C不终止Linux上的Python脚本。我用Ctrl+ \SIGQUIT)。

This post is old but I recently ran into the same problem of Ctrl+C not terminating Python scripts on Linux. I used Ctrl+\ (SIGQUIT).


回答 5

Ctrl+ DWindows和Linux的区别

事实证明,像Python 3.6,Python的口译手柄Ctrl+ C不同的Linux和Windows。对于Linux,Ctrl+ C会的工作主要预期但是在Windows Ctrl+ C 大多没有特别的工作,如果Python是运行阻塞调用,如thread.join或等待网页响应。它确实适用于time.sleep。这是Python解释器中发生的事情的很好的解释。注意Ctrl+ C生成SIGINT

解决方案1:使用Ctrl+ Break或等效项

在终端/控制台窗口中使用下面的键盘快捷键,这些快捷键将SIGBREAK在OS的较低级别生成并终止Python解释器。

Mac OS和Linux

Ctrl+ Shift+ \Ctrl+\

Windows

  • 一般:Ctrl+Break
  • 戴尔:Ctrl+ Fn+ F6Ctrl+ Fn+S
  • 联想:Ctrl+ Fn+ F11Ctrl+ Fn+B
  • HP:Ctrl+ Fn+Shift
  • 三星:Fn+Esc

解决方案2:使用Windows API

以下是一些方便的功能,这些功能将检测Windows并在控制台中为Ctrl+ 安装自定义处理程序C

#win_ctrl_c.py

import sys

def handler(a,b=None):
    sys.exit(1)
def install_handler():
    if sys.platform == "win32":
        import win32api
        win32api.SetConsoleCtrlHandler(handler, True)

您可以像上面这样使用:

import threading
import time
import win_ctrl_c

# do something that will block
def work():
    time.sleep(10000)        
t = threading.Thread(target=work)
t.daemon = True
t.start()

#install handler
install_handler()

# now block
t.join()

#Ctrl+C works now!

解决方案3:轮询方法

我不喜欢或不推荐这种方法,因为它不必要地消耗了处理器并降低了对性能的影响。

导入线程导入时间

def work():
    time.sleep(10000)        
t = threading.Thread(target=work)
t.daemon = True
t.start()
while(True):
    t.join(0.1) #100ms ~ typical human response
# you will get KeyboardIntrupt exception

Ctrl+D Difference for Windows and Linux

It turns out that as of Python 3.6, the Python interpreter handles Ctrl+C differently for Linux and Windows. For Linux, Ctrl+C would work mostly as expected however on Windows Ctrl+C mostly doesn’t work especially if Python is running blocking call such as thread.join or waiting on web response. It does work for time.sleep, however. Here’s the nice explanation of what is going on in Python interpreter. Note that Ctrl+C generates SIGINT.

Solution 1: Use Ctrl+Break or Equivalent

Use below keyboard shortcuts in terminal/console window which will generate SIGBREAK at lower level in OS and terminate the Python interpreter.

Mac OS and Linux

Ctrl+Shift+\ or Ctrl+\

Windows:

  • General: Ctrl+Break
  • Dell: Ctrl+Fn+F6 or Ctrl+Fn+S
  • Lenovo: Ctrl+Fn+F11 or Ctrl+Fn+B
  • HP: Ctrl+Fn+Shift
  • Samsung: Fn+Esc

Solution 2: Use Windows API

Below are handy functions which will detect Windows and install custom handler for Ctrl+C in console:

#win_ctrl_c.py

import sys

def handler(a,b=None):
    sys.exit(1)
def install_handler():
    if sys.platform == "win32":
        import win32api
        win32api.SetConsoleCtrlHandler(handler, True)

You can use above like this:

import threading
import time
import win_ctrl_c

# do something that will block
def work():
    time.sleep(10000)        
t = threading.Thread(target=work)
t.daemon = True
t.start()

#install handler
install_handler()

# now block
t.join()

#Ctrl+C works now!

Solution 3: Polling method

I don’t prefer or recommend this method because it unnecessarily consumes processor and power negatively impacting the performance.

import threading import time

def work():
    time.sleep(10000)        
t = threading.Thread(target=work)
t.daemon = True
t.start()
while(True):
    t.join(0.1) #100ms ~ typical human response
# you will get KeyboardIntrupt exception

回答 6

在Mac上,按Ctrl+ \退出连接到终端的python进程。

On Mac press Ctrl+\ to quit a python process attached to a terminal.


回答 7

在Mac上/在Terminal中:

  1. 显示检查器(在终端窗口中或在Shell>显示检查器上单击鼠标右键)
  2. 点击“运行进程”上方的设置图标
  3. 从“信号处理组”下的选项列表中选择(杀死,终止,中断等)。

On a mac / in Terminal:

  1. Show Inspector (right click within the terminal window or Shell >Show Inspector)
  2. click the Settings icon above “running processes”
  3. choose from the list of options under “Signal Process Group” (Kill, terminate, interrupt, etc).

回答 8

  • 使用Alt + F4强制关闭程序(关闭当前程序)
  • 向CMD的X按钮发送垃圾邮件,例如
  • Taskmanager(首先是Windows + R,然后是“ taskmgr”),然后结束任务。

这些可能会有所帮助。

  • Forcing the program to close using Alt+F4 (shuts down current program)
  • Spamming the X button on CMD for e.x.
  • Taskmanager (first Windows+R and then “taskmgr”) and then end the task.

Those may help.


回答 9

您可以打开任务管理器(Ctrl + Alt + Delete,然后转到任务管理器)并在其中查找python,然后调用服务器(例如)_go_app(命名约定为_language_app)。

如果结束_go_app任务,它将结束服务器,因此在浏览器中显示该消息“意外结束”,我也使用git bash,当我启动服务器时,无法在bash的外壳中脱离该服务器使用ctrl + c或ctrl +暂停,但是一旦您结束python任务(使用63.7 mb的任务),它将脱离bash中的服务器脚本,并允许我使用git bash shell。

You can open your task manager (ctrl + alt + delete, then go to task manager) and look through it for python and the server is called (for the example) _go_app (naming convention is: _language_app).

If I end the _go_app task it’ll end the server, so going there in the browser will say it “unexpectedly ended”, I also use git bash, and when I start a server, I cannot break out of the server in bash’s shell with ctrl + c or ctrl + pause, but once you end the python task (the one using 63.7 mb) it’ll break out of the server script in bash, and allow me to use the git bash shell.


回答 10

根据记录,在我的Raspberry 3B +(运行raspbian)上杀死进程的原因是Ctrl+ '。在我的法语AZERTY键盘上,触摸'也是4。

For the record, what killed the process on my Raspberry 3B+ (running raspbian) was Ctrl+'. On my French AZERTY keyboard, the touch ' is also number 4.