我有一个使用线程并发出大量HTTP请求的python脚本.我认为发生的事情是,当HTTP请求(使用urllib2)正在读取时,它会阻塞并且不响应CtrlC以停止程序.有没有办法解决?
Den*_*kov 160
在Windows上,唯一可靠的方法是使用CtrlBreak.立即停止每个python脚本!
(请注意,在某些键盘上,"Break"标记为"Pause".)
Dav*_*cke 74
在python程序运行时按Ctrl+ c将导致python引发KeyboardInterupt异常.生成大量HTTP请求的程序可能会有很多异常处理代码.如果try-except块的except部分没有指定它应该捕获的异常,它将捕获所有异常,包括你刚刚引起的KeyboardInterupt.正确编码的python程序将使用python异常层次结构,并仅捕获从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
Run Code Online (Sandbox Code Playgroud)
如果您无法更改代码(或需要终止程序以使更改生效),那么您可以尝试快速按Ctrl+ c.第一个KeyboardInterupt异常会将你的程序从try块中删除,希望当程序在try块之外时,会引发一个后来的KeyboardInterrupt异常.
And*_*are 50
如果它在Python shell中运行,则使用Ctrl+ Z,否则找到该python
进程并将其终止.
not*_*bit 30
中断过程取决于硬件和操作系统.因此,根据您运行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
Run Code Online (Sandbox Code Playgroud)
因此,如果你想在linux系统上捕获CTRL+BREAK
信号,你必须检查他们映射该键的POSIX信号.热门映射是:
CTRL+\ = SIGQUIT
CTRL+D = SIGQUIT
CTRL+C = SIGINT
CTRL+Z = SIGTSTOP
CTRL+BREAK = SIGKILL or SIGTERM or SIGSTOP
Run Code Online (Sandbox Code Playgroud)
实际上,在Linux下可以使用更多的功能,其中SysRq(系统请求)密钥可以使用它自己的生命 ......
Windows和Linux的Ctrl + C区别
事实证明,从Python 3.6开始,Python解释器对Linux和Windows的Ctrl + C处理方式有所不同。对于Linux,Ctrl + C 几乎可以按预期工作,但是在Windows上,Ctrl + C 大部分不起作用,特别是如果Python正在运行阻塞调用(例如,thread.join
等待Web响应)。它确实适用于time.sleep
。这是Python解释器中发生的事情的很好的解释。请注意,Ctrl + C会生成SIGINT。
解决方案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)
Run Code Online (Sandbox Code Playgroud)
您可以像上面这样使用:
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!
Run Code Online (Sandbox Code Playgroud)
解决方案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
Run Code Online (Sandbox Code Playgroud)
捕获(通过按+KeyboardInterrupt
启动)并强制退出:ctrl
c
from sys import exit
try:
# Your code
command = input('Type your command: ')
except KeyboardInterrupt:
# User interrupt the program with ctrl+c
exit()
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
158968 次 |
最近记录: |