【问题标题】:What are the Python thread + Unix signals semantics?Python 线程 + Unix 信号语义是什么?
【发布时间】:2010-11-14 09:57:55
【问题描述】:

围绕 Python 线程的规则是什么以及如何处理 Unix 信号?

SIGINT触发但由Python运行时内部处理的KeyboardInterrupt是否有不同的处理方式?

【问题讨论】:

    标签: python unix multithreading posix signals


    【解决方案1】:

    首先,当使用signal 模块设置信号处理程序时,您必须在主线程中创建它们。如果您尝试在单独的线程中创建它们,您将收到异常。

    通过signal.signal() 函数注册的信号处理程序将始终在主线程中调用。在支持向线程发送信号的架构上,在 C 级别上,我相信 Python 运行时会忽略线程上的所有信号,并且在主线程上有一个信号处理程序,它使用它来分派到您的 Python 代码信号处理程序。

    thread 模块的文档指出,KeyboardInterrupt 异常(通常由 SIGINT 触发)可以是 delivered to an arbitrary thread,除非您有可用的 signal 模块,所有 Unix 系统都应该有。在这种情况下,它被传递到主线程。如果您在没有signal 的系统上,则必须在线程中捕获KeyboardInterrupt 并调用thread.interrupt_main() 以在主线程中重新引发它。

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

    【讨论】:

    • 有趣,我以为只有主线程会收到KeyboardInterrupts。
    • 是的!谁知道为什么不是。
    • 根据我的经验,并通过阅读文档,当signal 模块可用时,KeyboardInterrupt 仅传递到主线程。
    • 迈尔斯:是的,我认为你和巴斯蒂安是对的。快速检查一些 python-list 帖子并查看支持它的代码。我已经更正了答案。谢谢!
    【解决方案2】:

    来自signal 文档:

    如果在同一个程序中同时使用信号和线程,则必须小心。同时使用信号和线程时要记住的基本事项是:始终在执行的主线程中执行signal() 操作。任何线程都可以执行alarm()getsignal()pause()setitimer()getitimer();只有主线程可以设置新的信号处理程序,并且主线程将是唯一接收信号的线程(这是由 Python 信号模块强制执行的,即使底层线程实现支持向单个线程发送信号)。这意味着信号不能用作线程间通信的手段。请改用锁。

    【讨论】:

      猜你喜欢
      • 2010-09-19
      • 1970-01-01
      • 2014-08-29
      • 1970-01-01
      • 2017-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多