python - 从Python中的外部模块退出(信号处理)

标签 python module try-catch exit signal-handling

我写了一个小脚本,用 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/

相关文章:

python统计前10名

python - ThreadPoolExecutor + Requests == 死锁?

python - 使用Rawpy读取tensorflow的map方法内的原始图像文件

python - 安装模块时无模块错误

javascript - 如何从 Node.js 模块内部引用该模块的上下文对象?

multithreading - Perl 线程 - 捕获退出

python - 比较/组合两个字典

css - BackOffice 模块配置 CSS

ios - Objective-C try-catch - 为什么编译?为什么返回不同的构建调试与发布?

PHP(或其他): Strategy to deal with exceptions that "cannot occur"