Python线程与Unix信号的语义是什么?
关于Python线程和Unix信号的规则是什么呢?
KeyboardInterrupt
是由SIGINT
触发的,但它是由Python运行时内部处理的,这种处理方式有什么不同吗?
2 个回答
4
来自 signal
文档的内容:
如果在同一个程序中同时使用信号和线程,必须小心处理。使用信号和线程时要记住的最重要一点是:一定要在主线程中进行
signal()
操作。任何线程都可以执行alarm()
、getsignal()
、pause()
、setitimer()
或getitimer()
;但只有主线程可以设置新的信号处理器,并且只有主线程会接收到信号(这一点是由 Python 的信号模块强制执行的,即使底层的线程实现支持将信号发送到单独的线程)。这意味着信号不能用作线程之间的通信方式。建议使用锁来代替。
9
首先,在使用 signal
模块设置信号处理器时,必须在主线程中创建它们。如果你尝试在其他线程中创建,就会出现错误。
通过 signal.signal()
函数注册的信号处理器总是在主线程中被调用。在支持向线程发送信号的架构上,Python运行时在C层面上会忽略线程中的所有信号,并在主线程上有一个信号处理器,用来转发到你的Python代码信号处理器。
thread
模块的文档说明,KeyboardInterrupt
异常(通常是由 SIGINT
触发的)可以被 发送到任意线程,除非你有 signal
模块可用,所有Unix系统都应该有这个模块。在这种情况下,它会被发送到主线程。如果你在一个没有 signal
的系统上,你需要在你的线程中捕获 KeyboardInterrupt
,然后调用 thread.interrupt_main()
来在主线程中重新抛出它。