使用 ctrl + c 停止 python

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

249222 次浏览

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

在 Windows 上,唯一可靠的方法是使用 CtrlBreak。立即停止每个 Python 脚本!

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

在 Python 程序运行时按 Ctrl + c将导致 python 引发 KeyboardInterrupt异常。发出大量 HTTP 请求的程序很可能会有大量异常处理代码。如果 try-except块的 except部分没有指定应该捕获哪些异常,那么它将捕获所有异常,包括您刚刚导致的 KeyboardInterrupt。正确编码的 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

如果不能更改代码(或者需要终止程序以使更改生效) ,那么可以尝试快速按 Ctrl + c。第一个 KeyboardInterrupt异常将把程序踢出 try块,当程序位于 try块之外时,希望后面的一个 KeyboardInterrupt异常将被引发。

中断过程依赖于硬件和操作系统。因此,根据运行 Python 脚本的位置,您的行为会有很大的不同。例如,在 Windows 机器上,我们有 Ctrl + C(SIGINT)和 Ctrl + Break(SIGBREAK)。

所以虽然 SIGINT 在所有系统上都存在并且可以被处理和捕获,SIGBREak 信号是 Windows 特有的(在 配置系统中可以被禁用) ,并且真正被 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 信号,您必须检查哪个 POSIX 信号映射了那个键。流行的地图有:

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

实际上,在 Linux 下还有更多的函数可用,其中 SysRq(System Request)键可以接受 拥有自己的生命..。

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

在 Mac/in 终端上:

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

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

  • 强制程序关闭使用 Alt + F4(关闭当前程序)
  • 在 CMD 上为 e.x 发送 X 按钮。
  • 任务管理器(首先是 Windows + R,然后是“ taskmgr”) ,然后结束任务。

这些可能会有帮助。

适用于 Windows 和 Linux 的 Ctrl + D差异

事实证明,在 Python 3.6中,Python 解释器对 Linux 和 Windows 的 Ctrl + C处理方式不同。对于 Linux 来说,Ctrl + C可以像预期的那样工作在 time.sleep1上,但是在 Windows Ctrl + C time.sleep1不能工作,特别是当 Python 运行阻塞调用(如 thread.join)或等待 Web 响应时。然而,它确实适用于 time.sleep。下面是 Python 解释器中的 time.sleep3。请注意,Ctrl + C生成 SIGINT

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

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

Mac OS 和 Linux

Ctrl + Shift + \Ctrl + < kbd >

视窗 :

  • 一般情况: Ctrl + Break
  • 戴尔: Ctrl + Fn + F6Ctrl + Fn + S
  • 联想: Ctrl + Fn + F11Ctrl + 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: 轮询方法

我不喜欢或推荐这种方法,因为它不必要地消耗处理器和电源,从而对性能产生负面影响。

    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

顺便说一句,在我的 Raspberry 3B + (运行 raspbian)上杀死进程的是 Ctrl + '。在我的法语 AZERTY 键盘上,触摸 '也是第4个键。

你可以打开你的任务管理器(ctrl + alt + delete,然后进入任务管理器)查找 python,服务器被调用(例如) _ go _ app (变数命名原则是: _ language _ app)。

如果我结束了 _ go _ app 任务,它将结束服务器,所以在浏览器中会显示它“意外结束”,我也使用 git bash,当我启动一个服务器时,我不能用 ctrl + c 或 ctrl + stop 从 bash 的 shell 中脱离服务器,但是一旦你结束了 python 任务(使用63.7 mb 的那个) ,它将脱离 bash 中的服务器脚本,并允许我使用 git bash shell。enter image description here

捕捉 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()