我写了一个小脚本,用 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/ block 内。如果这是问题所在,我如何退出该信号处理模块?如果这不是问题,那是什么问题呢?
最佳答案
信号处理不在主线程中完成,因此调用 sys.exit() 不会起到停止主线程的作用。实际上,调用它只会引发一个特殊的内部异常(SystemExit
),如果未捕获,它将终止当前线程。没有 Python 内部标准方法来向一个线程发出信号以请终止,因此结束信号处理线程不会终止主线程。
您有多种选择。
一种方法是检查 longrunner 线程内部是否存在某种条件(全局变量或 threading.Condition 或类似条件),如果该状态为“请终止”,则停止循环。
另一种方法是使用操作系统的功能并终止进程及其所有线程(例如,通过向自己发送一个您没有捕获的信号,例如 SIGKILL)。
关于python - 从Python中的外部模块退出(信号处理),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19361946/