gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 16:56:41 27 4
gpt4 key购买 nike

我有一个线程化的 Python 守护进程。像任何好的守护进程一样,它想要启动它的所有工作线程,然后等待直到它被告知终止。正常的终止信号是 SIGTERM,在大多数语言中,我会通过等待事件或互斥量来终止,因此使用 threading.Event 对我来说很有意义。问题是 Python 的 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 被传递(即,除了退出之外,“handled”永远不会被打印):

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. 我是否以某种方式滥用了 threading.Event
  2. 如果我不是,除了第一个示例中的轮询和 sleep 机制之外,还有其他选择吗?
  3. 另外,如果我不是,为什么使用 threading.Event 会终止信号处理程序?

最佳答案

来自 Python documentation on signals :

Although Python signal handlers are called asynchronously as far as the Python user is concerned, they can only occur between the “atomic” instructions of the Python interpreter. This means that signals arriving during long calculations implemented purely in C (such as regular expression matches on large bodies of text) may be delayed for an arbitrary amount of time.

我测试了各种 threadingthread 类,但没有一个按您想要的方式工作——这可能是因为 Python 处理信号的方式。

但是,在 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 上检查过它,它可以工作。如果您的应用程序不使用很多其他信号,我认为它不再归类为轮询和 sleep 。

处理SIGINTSIGHUP也很好,可以正确处理用户中断(通常是按Ctrl+C)和用户断开连接(分别关闭父终端。

另外,请注意 signal.pause()在 Windows 系统上不可用

关于python - 为什么使用 threading.Event 导致 SIGTERM 未被捕获?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3102163/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com