1

我写了一个小脚本,在 Python 中做了一些非常耗时的事情,我包含了一个信号处理模块,它监听 SIGINT、SIGQUIT 和 SIGINFO,当用户输入 SIGQUIT 或 SIGINFO 时打印状态,并在 SIGINT( CTRL-C) 被输入。该代码非常草率,因为我在几分钟内将其破解并窃取了一些外国代码-别担心,我(或者更确切地说,您,因为我被卡住了)发现错误后立即清理它:

def setup_signals(progress_bar):
import signal
import sys

def progress(*args):
    print(progress_bar)

def killitwithfire(*args):
    print("[x] User interrupted with CTRL-C. Aborting.")
    sys.exit(0)

for sig in (signal.SIGINFO, signal.SIGQUIT):
    signal.signal(sig, progress)
for sig in (signal.SIGINT,):
    signal.signal(sig, killitwithfire)
print("Sig handlers built:\n Press Ctrl+T(BSD/OS X) or Ctrf+4(Linux) for progress.")
print("Press CTRL-C to abort.")

现在,问题是当输入 CTRL-C 时,killitwithfire() 中的消息 - 抱歉引用错误 - 被打印,但它不会退出。

执行此操作的代码位于 try/catch/ 块内。如果这是问题所在,我该如何退出这个信号处理模块?如果不是问题,那是什么?

4

1 回答 1

1

信号处理不在主线程中完成,因此调用sys.exit()不会起到停止主线程的作用。实际上,调用它只会引发一个特殊的内部异常 ( SystemExit),如果未被捕获,它将终止当前线程。没有 python 内部标准的方式来通知一个线程请终止,因此结束信号处理线程不会终止主线程。

你有几个选择。

一种是检查 longrunner 线程内部的某个条件(全局变量threading.Condition或类似情况),如果此状态为“请终止”,则停止循环。

另一种方法是使用操作系统的工具并终止您的进程及其所有线程(例如,通过向您自己发送一个您没有捕捉到的信号,例如SIGKILL)。

于 2013-10-14T14:07:11.873 回答