python多进程守护进程中的僵尸进程

2024-04-24 10:49:06 发布

您现在位置:Python中文网/ 问答频道 /正文

在研究了python守护进程之后,这次遍历似乎是最健壮的:http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/

现在我试图在daemon类中实现一个工作池,我相信这个工作池正在工作(我还没有彻底测试代码),除了在关闭时我得到一个僵尸进程。我已经读过了,我需要等待孩子的返回代码,但我只是还不能确切地看到我需要怎么做。

下面是一些代码片段:

def stop(self):
    ...
    try:
        while 1:
            self.pool.close()
            self.pool.join()
            os.kill(pid, SIGTERM)
            time.sleep(0.1)
    ...

在这里,我尝试了os.killpg和许多os.wait方法,但没有任何改进。我还玩过closing/joining游泳池前后的os.kill。这个循环保持不变,永远不会结束,一旦它到达os.kill我就会得到一个僵尸进程。self.pool = Pool(processes=4)出现在守护进程的__init__部分。从run(self)(在start(self)之后执行)中,我将调用self.pool.apply_async(self.runCmd, [cmd, 10], callback=self.logOutput)。不过,在调查之前,我想先解决这个僵尸进程。

如何在守护进程内正确实现池以避免此僵尸进程?


Tags: 代码selfcomhttp进程oswwwunix
1条回答
网友
1楼 · 发布于 2024-04-24 10:49:06

在不知道子进程/守护进程中发生了什么情况的情况下,不可能对答案有100%的信心,但请考虑这是否可能。由于子进程中有工作线程,因此在收到SIGTERM后,实际上需要构建一些逻辑来连接所有这些线程。否则,您的进程可能无法退出(即使退出,您也可能无法正常退出)。为此,您需要:

  • 编写一个信号处理程序,用于捕获SIGTERM信号并为主线程触发事件的子/守护进程
  • 在子/守护进程的主线程(非常重要)中安装信号处理程序
  • SIGTERM的事件处理程序必须向子/守护进程中的所有线程发出停止指令
  • 所有线程在完成时都必须是join()ed(如果您假设SIGTERM会自动销毁您可能需要实现此逻辑的所有内容)
  • 一旦所有东西都连接起来并清理干净,就可以退出主线程

如果您有用于I/O和所有类型的线程,那么这将是一个真正的杂务。

另外,我通过实验发现,在使用信号处理程序时,事件侦听器的特定策略很重要。例如,如果使用select.select(),则必须使用超时,如果发生超时,则重试;否则,信号处理程序将不会运行。如果事件有Queue.Queue对象,并且事件侦听器调用其.get()方法,则必须使用超时,否则信号处理程序将不会运行。(在VM中用C实现的“real”信号处理程序运行,但是除非使用超时,否则Python信号处理程序不会运行。)

祝你好运!

相关问题 更多 >