【发布时间】:2010-11-14 09:57:55
【问题描述】:
围绕 Python 线程的规则是什么以及如何处理 Unix 信号?
由SIGINT触发但由Python运行时内部处理的KeyboardInterrupt是否有不同的处理方式?
【问题讨论】:
标签: python unix multithreading posix signals
围绕 Python 线程的规则是什么以及如何处理 Unix 信号?
由SIGINT触发但由Python运行时内部处理的KeyboardInterrupt是否有不同的处理方式?
【问题讨论】:
标签: python unix multithreading posix signals
首先,当使用signal 模块设置信号处理程序时,您必须在主线程中创建它们。如果您尝试在单独的线程中创建它们,您将收到异常。
通过signal.signal() 函数注册的信号处理程序将始终在主线程中调用。在支持向线程发送信号的架构上,在 C 级别上,我相信 Python 运行时会忽略线程上的所有信号,并且在主线程上有一个信号处理程序,它使用它来分派到您的 Python 代码信号处理程序。
thread 模块的文档指出,KeyboardInterrupt 异常(通常由 SIGINT 触发)可以是 delivered to an arbitrary thread,除非您有可用的 signal 模块,所有 Unix 系统都应该有。在这种情况下,它被传递到主线程。如果您在没有signal 的系统上,则必须在线程中捕获KeyboardInterrupt 并调用thread.interrupt_main() 以在主线程中重新引发它。
【讨论】:
KeyboardInterrupts。
signal 模块可用时,KeyboardInterrupt 仅传递到主线程。
来自signal 文档:
如果在同一个程序中同时使用信号和线程,则必须小心。同时使用信号和线程时要记住的基本事项是:始终在执行的主线程中执行
signal()操作。任何线程都可以执行alarm()、getsignal()、pause()、setitimer()或getitimer();只有主线程可以设置新的信号处理程序,并且主线程将是唯一接收信号的线程(这是由 Python 信号模块强制执行的,即使底层线程实现支持向单个线程发送信号)。这意味着信号不能用作线程间通信的手段。请改用锁。
【讨论】: