我有一个使用线程并发出大量HTTP请求的python脚本。我认为发生的事情是,当HTTP请求(使用urllib2)正在读取时,它会阻塞并且不响应 Ctrl C 来停止程序。有没有办法解决这个问题?
答案 0 :(得分:151)
在Windows上,唯一可靠的方法是使用 Ctrl Break 。立即停止每个python脚本!
(请注意,在某些键盘上,“Break”标记为“Pause”。)
答案 1 :(得分:65)
在python程序运行时按 Ctrl + c 将导致python引发KeyboardInterupt异常。生成大量HTTP请求的程序可能会有很多异常处理代码。如果try-except块的except部分没有指定它应该捕获的异常,它将捕获所有异常,包括你刚刚引起的KeyboardInterupt。正确编码的python程序将使用python exception hierarchy并仅捕获从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 KeyboardInterupt
如果您无法更改代码(或需要终止程序以使更改生效),那么您可以尝试快速按 Ctrl + c 。第一个KeyboardInterupt异常会将你的程序从try块中删除,希望当程序在try块之外时,会引发一个后来的KeyboardInterrupt异常。
答案 2 :(得分:47)
如果它在Python shell中运行,请使用 Ctrl + Z ,否则找到python
进程并将其终止。
答案 3 :(得分:29)
中断过程取决于硬件和操作系统。因此,根据您运行python脚本的位置,您将拥有非常不同的行为。例如,在Windows机器上,我们有 Ctrl + C (SIGINT
)和 Ctrl + Break (SIGBREAK
)。
因此,虽然SIGINT存在于所有系统上并且可以处理和捕获,但SIGBREAK信号是Windows特定的(并且可以在 CONFIG.SYS 中禁用)并且实际上由BIOS处理中断向量INT 1Bh,这就是为什么这个键比任何其他键更强大的原因。因此,如果你正在使用一些* nix风格的操作系统,你会得到不同的结果,具体取决于实现,因为那里没有那个信号,但其他信号。在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
signal,您必须检查他们映射该密钥的POSIX signal。热门映射是:
CTRL+\ = SIGQUIT
CTRL+D = SIGQUIT
CTRL+C = SIGINT
CTRL+Z = SIGTSTOP
CTRL+BREAK = SIGKILL or SIGTERM or SIGSTOP
事实上,在Linux下可以使用更多功能,其中 SysRq (系统请求)密钥可以使用a life of its own ...
答案 4 :(得分:16)
这篇文章很老但我最近遇到了同样的CTRL+C
问题没有终止我Linux
上的python脚本。我使用了CTRL + \
(SIGQUIT
)。
答案 5 :(得分:6)
Windows和Linux的Ctrl + C差异
事实证明,从Python 3.6开始,对于Linux和Windows,解释器对Ctrl + C生成的SIGINT的处理方式有所不同。对于Linux,按ctrl + c可以按预期大部分工作,但是在Windows上,如果通话受阻塞,例如thread.join
或等待,则按ctrl + c基本上按 不起作用网络响应(但是确实适用于time.sleep
)。这是Python解释器中发生的事情的nice explanation。
解决方案1:使用Ctrl + Break或同等功能
在终端/控制台窗口中使用下面的键盘快捷键,这些快捷键将在操作系统的较低级别生成SIGBREAK,并终止Python解释器。
Mac OS和Linux
Ctrl + Shift + \ or
Ctrl + \
Windows :
Ctrl+Break
Ctrl+Fn+F6
或Ctrl+Fn+S
Ctrl+Fn+F11
或Ctrl+Fn+B
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
答案 6 :(得分:4)
在Mac上按:
"控制" +" \"
退出连接到终端的python进程。
答案 7 :(得分:1)
在Mac / in终端上:
答案 8 :(得分:0)
可能有帮助。
答案 9 :(得分:0)
记录下来,杀死我的Raspberry 3B +(运行raspbian)的进程是:
CTRL + '
在我的法语AZERTY键盘上,触摸'也是数字4。
答案 10 :(得分:0)
您可以打开任务管理器(按Ctrl + Alt +删除,然后转到任务管理器)并在其中查找python,然后调用服务器(例如)_go_app(命名约定为_language_app)。
如果我结束_go_app任务,它将结束服务器,因此在浏览器中显示该消息“意外结束”,我也使用git bash,并且当我启动服务器时,我无法脱离服务器在bash的ctrl + c或ctrl +暂停的shell中,但是一旦您结束python任务(使用63.7 mb的python任务),它将脱离bash中的服务器脚本,并允许我使用git bash shell。
答案 11 :(得分:0)
您可以尝试以下方法:
<h2>With padding removed</h2>
<div class="list-wrapper">
<ul class="with-padding-removed">
<li>Expensive breeds</li>
<li>Cat memes</li>
<li>Adopt</li>
<li>Cat pictures</li>
<li>Best breeds</li>
</ul>
</div>
<hr/>
<h2>Without padding removed</h2>
<div class="list-wrapper">
<ul class="without-padding-removed">
<li>Expensive breeds</li>
<li>Cat memes</li>
<li>Adopt</li>
<li>Cat pictures</li>
<li>Best breeds</li>
</ul>
</div>
当用户按下from sys import exit
try:
# Your code
command = input('Type your command: ')
except KeyboardInterrupt:
# User interrupt the program with ctrl+c
exit()
+ ctrl