python - python多处理守护进程中的僵尸进程

标签 python daemon multiprocessing zombie-process

在研究了 python 守护进程之后,这个演练似乎是最可靠的:http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/

现在我正在尝试在守护程序类中实现一个工作池,我认为它正在工作(我没有彻底测试代码),除了在关闭时我得到一个僵尸进程。我已经阅读过我需要等待 child 的返回码,但我还不能确切地看到我需要怎么做。

下面是一些代码片段:

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

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

我怎样才能在守护进程中正确地实现池来避免这个僵尸进程?

最佳答案

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

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

如果您有用于 I/O 和各种事情的线程,那么这将是一件真正的苦差事。

此外,我通过实验发现,当您使用信号处理程序时,事件监听器的特定策略很重要。例如,如果您使用 select.select() ,则必须使用超时并在发生超时时重试;否则你的信号处理程序将不会运行。如果您有一个用于事件的 Queue.Queue 对象,并且您的事件监听器调用它的 .get() 方法,您必须使用超时,否则您的信号处理程序将不会运行。 (在 VM 中以 C 语言实现的“真正的”信号处理程序运行,但您的 Python 信号处理程序不会运行,除非您使用超时。)

祝你好运!

关于python - python多处理守护进程中的僵尸进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6428842/

相关文章:

python - 更改默认 python 后 netplan 不工作

python:psycopg2:psql:删除条件所在的行

python - 带有 Tkinter 的 Python 中带有 CheckButtons 的列表框

java - Tomcat(或等价物)对简单服务的好处

linux - 每 2 秒检查一次目录内容,如果 bash 中存在某个文件,则复制其内容

python - 从 multiprocessing.process for a loop 获取结果

c - 如何在fork()中的一个子进程中执行多个任务

python - 如何告诉 pip 在安装我的包时创建文件夹

boost - 用 mingw 编译 dogecoind.exe

python - 清理从 Flask MethodView API 启动的长时间运行的子进程