代码之家  ›  专栏  ›  技术社区  ›  Benjamin Pollack Stefan Rusek

为什么使用threading.Event会导致SIGTERM未被捕获?

  •  15
  • Benjamin Pollack Stefan Rusek  · 技术社区  · 16 年前

    SIGTERM ,在大多数语言中,我都会通过等待事件或互斥来终止,所以使用 threading.Event Event 对象和Unix信号似乎不能很好地结合在一起。

    SIGTERM公司 :

    import signal
    import time
    
    RUN = True
    
    def handle(a, b):
        global RUN
        print "handled"
        RUN = False
    
    signal.signal(signal.SIGTERM, handle)
    while RUN:
        time.sleep(0.250)
    print "Stopping"
    

    但这不会导致 SIGTERM公司 交付时(即,除退出外,“已处理”从不打印):

    import signal
    import threading
    
    RUN_EVENT = threading.Event()
    
    def handle(a, b):
        print "handled"
        RUN_EVENT.set()
    
    signal.signal(signal.SIGTERM, handle)
    RUN_EVENT.wait()
    print "Stopping"
    

    所以我的问题是:

    1. 线程。事件 在某种程度上?
    2. 如果我不是,为什么要用 线程。事件 杀死信号处理器?
    1 回复  |  直到 16 年前
        1
  •  16
  •   Masood Khaari    6 年前

    Python documentation on signals :

    尽管对于Python用户来说,Python信号处理程序是异步调用的,但是它们只能在Python解释器的原子指令之间发生。这意味着在纯用C语言实现的长时间计算过程中到达的信号(例如大型文本体上的正则表达式匹配)可能会延迟任意时间。

    我测试了各种 threading thread

    signal 然而,有一个 pause() 在进程接收到信号之前休眠的函数。修改后的示例如下所示:

    import signal
    
    RUN = True
    
    def handle(a, b):
        global RUN
        print "handled"
        RUN = False
    
    signal.signal(signal.SIGTERM, handle)
    signal.signal(signal.SIGINT, handle)
    signal.signal(signal.SIGHUP, handle)
    
    while RUN:
        signal.pause()
    
    print "Stopping"
    

    我在Linux上查过了,可以用。我认为如果你的应用程序不使用很多其他信号,它就不再被归类为轮询和睡眠。

    SIGINT SIGHUP 为了正确处理用户中断(通常按 Ctrl+C )以及用户断开连接(关闭父终端)。

    signal.pause() 在Windows系统上。

        2
  •  3
  •   Masood Khaari    6 年前

    在Python3中,这是可行的:

    from threading import Event
    from os import getpid
    from signal import SIGTERM, SIGINT, SIGHUP, signal
    
    stop_event = Event()
    
    def handler(signum, frame):
        stop_event.set()
    
    def main():
        signal(SIGTERM, handler)
        signal(SIGINT, handler)
        signal(SIGHUP, handler)
        print('start, pid:', getpid())
        stop_event.wait()
        print('done')
    
    if __name__ == '__main__':
        main()
    

    看起来是这样的 Python 2.7版 仅当指定等待间隔时,它才起作用: stop_event.wait(number_of_seconds)