在 Python 3 中使用 SIGINT 杀死一个函数

Posted

技术标签:

【中文标题】在 Python 3 中使用 SIGINT 杀死一个函数【英文标题】:Using SIGINT to kill a function in Python 3 【发布时间】:2016-11-05 12:28:49 【问题描述】:

以如下代码为例:

import signal
import time

def stop(signal, frame):
    print("You pressed ctrl-c")
    # stop counter()

def counter():
    for i in range(20):
        print(i+1)
        time.sleep(0.2)

signal.signal(signal.SIGINT, stop)
while True:
    if(input("Do you want to count? ")=="yes"):
        counter()

如何让stop() 函数杀死或破坏counter() 函数以使其返回提示符?

输出示例:

Do you want to count? no
Do you want to count? yes
1
2
3
4
5
6
7
You pressed ctrl-c
Do you want to count?

我正在使用 Python 3.5.2。

【问题讨论】:

【参考方案1】:

您可以使用KeyboardInterrupt 异常而不是定义自己的SIGINT 处理程序:

while input("Do you want to count? ").strip().casefold() == "yes":
    try:
        counter()
    except KeyboardInterrupt:
        print("You pressed ctrl-c")

【讨论】:

我真的很喜欢它节省的空间量:)【参考方案2】:

您可以在stop 中引发异常,这将停止counter 的执行并搜索最近的异常处理程序(您在while True 循环中设置)。

即创建自定义异常:

class SigIntException(BaseException): pass

stop提出它:

def stop(signal, frame):
    print("You pressed ctrl-c")
    raise SigIntException

并在您的 while 循环中捕获它:

while True:
    if(input("Do you want to count? ")=="yes"):
        try:        
            counter()
        except SigIntException:
            pass

它会按照您需要的方式运行。

【讨论】:

天才!感谢您的帮助;D @EddieHart 要清楚,Python 中的默认 SIGINT 处理程序会引发 KeyboardInterrupt 异常,即默认情况下您不需要做任何事情来中断主线程中的 counter() 函数。 @J.F.Sebastian 是的,但据我所知,这会终止整个程序? @EddieHart:如果你想继续;像 Python 中的任何其他例外一样使用 try/except KeyboardInterrupt

以上是关于在 Python 3 中使用 SIGINT 杀死一个函数的主要内容,如果未能解决你的问题,请参考以下文章

ForkManager SIGINT 只杀死 fork 中的当前进程

C - 在 SIGINT 上释放分配的内存

SDL/C++ OpenGL 程序,如何阻止 SDL 捕获 SIGINT

使用 KeyboardInterrupt 异常捕获 SIGINT 在终端中有效,而不是在脚本中

使用 kill 命令杀死 java进程,你用对了吗?

C - SIGINT处理程序不能与多线程一起工作,每个线程都有一个popen进程。