Python线程与Unix信号的语义是什么?

8 投票
2 回答
1661 浏览
提问于 2025-04-15 13:12

关于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() 来在主线程中重新抛出它。

更多信息可以在Python文档中找到,关于 threadsignal 模块。

撰写回答