gpt4 book ai didi

Python 进程在重启后停止响应 SIGTERM/SIGINT

转载 作者:太空宇宙 更新时间:2023-11-03 14:35:35 33 4
gpt4 key购买 nike

我遇到一些使用看门狗进程运行的 python 进程的奇怪问题。

watchdog 进程是用 python 编写的并且是父进程,并且有一个名为 start_child(name) 的函数,它使用 subprocess.Popen 打开子进程。记录 Popen 对象,以便看门狗可以使用 poll() 监视进程,并最终在需要时使用 terminate() 结束它。如果 child 意外死亡,看门狗会再次调用 start_child(name) 并记录新的 Popen 对象。

有7个子进程,都是python的。如果我手动运行任何子级,我可以使用 kill 发送 SIGTERM 或 SIGINT 并获得我期望的结果(进程结束)。

但是,当从看门狗进程运行时,子进程只会在 FIRST 信号后结束。当看门狗重新启动子进程时,新的子进程不再响应 SIGTERM 或 SIGINT。我不知道是什么原因造成的。

看门狗.py

class watchdog:
# <snip> various init stuff

def start(self):
self.running = true

kids = ['app1', 'app2', 'app3', 'app4', 'app5', 'app6', 'app7']
self.processes = {}

for kid in kids:
self.start_child(kid)

self.thread = threading.Thread(target=self._monitor)
self.thread.start()

while self.running:
time.sleep(10)

def start_child(self, name):
try:
proc = subprocess.Popen(name)
self.processes[name] = proc
except:
print "oh no"
else:
print "started child ok"

def _monitor(self):
while self.running:
time.sleep(1)
if self.running:
for kid, proc in self.processes.iteritems():
if proc.poll() is not None: # process ended
self.start_child(kid)

所以发生的事情是 watchdog.start() 启动所有 7 个进程,如果我发送任何进程 SIGTERM,它就会结束,监控线程会再次启动它。但是,如果我随后发送新进程 SIGTERM,它会忽略它。

我应该能够一遍又一遍地向重新启动的进程发送 kill -15。为什么重启后就不管了?

最佳答案

如此处解释:http://blogs.gentoo.org/agaffney/2005/03/18/python_sucks ,当 Python 创建一个新线程时,它会阻止该线程的所有信号(以及该线程产生的任何进程)。

我使用通过 ctypes 调用的 sigprocmask 修复了这个问题。这可能是也可能不是“正确”的方法,但它确实有效。

在子进程中,在 __init__ 期间:

libc = ctypes.cdll.LoadLibrary("libc.so")
mask = '\x00' * 17 # 16 byte empty mask + null terminator
libc.sigprocmask(3, mask, None) # '3' on FreeBSD is the value for SIG_SETMASK

关于Python 进程在重启后停止响应 SIGTERM/SIGINT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1133693/

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