Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python多处理守护进程中的僵尸进程_Python_Daemon_Multiprocessing_Zombie Process - Fatal编程技术网

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

python多处理守护进程中的僵尸进程,python,daemon,multiprocessing,zombie-process,Python,Daemon,Multiprocessing,Zombie Process,在研究python守护进程之后,本演练似乎是最健壮的: 现在,我正在尝试在daemon类中实现一个工作人员池,我认为这个工作人员池正在工作(我还没有完全测试代码),但在结束时,我得到了一个僵尸进程。我已经阅读了我需要等待孩子返回的代码,但我只是不知道我到底需要怎么做 以下是一些代码片段: def stop(self): ... try: while 1: self.pool.close() self.pool.joi

在研究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
/
os.kill
之前和之后加入
池的游戏。这个循环一直存在,永远不会结束,一旦它到达
os.kill
我就会得到一个僵尸进程
self.pool=pool(processes=4)
出现在守护进程的
\uuuu init\uuuu
部分。从
run(self)
运行(self)
,我将调用
self.pool.apply\u async(self.runCmd,[cmd,10],callback=self.logOutput)
。然而,在研究之前,我想先解决这个僵尸过程


如何正确地执行守护进程内的池以避免这个僵尸进程?

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

  • 编写一个信号处理程序,用于捕获SIGTERM信号并触发主线程的事件的子/守护进程
  • 在子进程/守护进程的主线程(非常重要)中安装信号处理程序
  • SIGTERM的事件处理程序必须向子/守护进程中的所有线程发出停止指令
  • 所有线程在完成后都必须被join()绑定(如果您假设SIGTERM会自动销毁实现此逻辑所需的所有内容)
  • 连接并清理完所有内容后,可以退出主线程
如果您有用于I/O和各种事情的线程,那么这将是一件非常麻烦的事情

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


祝你好运

您的守护程序中有处理SIGCHLD的处理程序吗?没有,我没有这样的处理程序。我仅有的处理程序是在
runCmd()
函数中使用的超时,该函数是
signal.signal(signal.SIGALRM,self.handler)
。在这里,处理程序抛出一个自定义异常,表示命令已超过分配的执行时间。为什么我需要这个处理器?我认为多处理在
池中解决了这个问题。关闭
池。加入
。坦白地说,我不知道这个过程来自哪里,因为我没有调用
apply\u async
,因此我没有工作线程或回调线程。我更详细地研究了它,我不认为这是问题所在。然而,我意识到这篇文章对问题的描述非常缺乏。如果您仍然对这个问题感兴趣,我将在这里更详细地重新提问: