使用ctrl + c停止python


128

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


9
我不知道为什么,但是至少在OS X上,使用Control +反斜杠会导致它终止,并且您会看到“ python崩溃”对话框……很奇怪。并不是真正有用的信息,因此是注释!
micmoo

3
实际上,它适用于终端机中的所有应用程序…
micmoo

1
David Beazley已经描述了Ctrl / C中断如何将多线程Python脚本变成CPU猪。在这里(stackoverflow.com/questions/990102/…)上有Beazley的演讲的链接。
Ned Deily

Answers:


189

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

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


4
什么Break啊 如何输入?
u0b34a0f6ae

5
键盘上应该有一个Pause_Break按钮
-jonatron,

18
如果没有呢?我使用的是Intel Macbook,它没有功能非常齐全的键盘。
Bluu

53
在Linux上,你应该使用Ctrl-按住Shift \
米哈尔杰林斯基

12
ctrl + Z不会杀死脚本,它只是将其隐藏到后台并挂起。您可以键入fg来调用它。
Shady Xu

84

在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块外时引发稍后的异常之一。


1
这是启用最常见的“中断”(ctrl + c)的好答案。
Xerion '16

53

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


25
^Z-> [1]+ Stopped -> kill %1停止工作1(或bash所说的工作%1)
u0b34a0f6ae 2009年

23
值得一提的是,Ctrl + Z会暂停该过程。
Matteo Italia

2
要详细说明上述内容:暂停进程会将其保留在内存和外壳程序中,只会阻止其使用CPU资源。文件,套接字,所有内容仍处于打开和使用状态。实际上,键入fg将使它立即返回。
RandomInsano

2
Ctrl+Z不是停止python脚本的正确方法,除非您计划恢复已暂停的进程,否则应避免使用该方法。
Josh Correia

33

中断过程取决于硬件和操作系统。因此,根据运行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(系统请求)键可以保留自己的生命 ...


19

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


尽管它将导致核心转储,但确实停止了脚本,谢谢
ospider

17

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

不,在Ubuntu上,对于python 2.7和3.6,按ctrl + c不会退出但显示KeyboardInterrupt
瑞克(Rick)


3

在Mac上/在Terminal中:

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

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

这些可能会有所帮助。


1

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

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


1

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.