Python:为什么一个进程在完成运行后仍保持活动状态()

时间:2016-02-18 05:21:34

标签: python python-2.7 multiprocessing python-multiprocessing

我有一个多处理程序,它启动了一组进程。这些程序的run()部分是这样的:

def run(self):
    self.prep()
    self._prn('Started with PID {pid}'.format(pid=self.pid))
    while True:
        job = self._queue.get()
        if job is None: break
        self.do_work(**job)
    self._prn('Received spindown signal.')

_prn方法只是简单地添加了Process的名称,如下所示:)

def _prn(self, *args, **kwargs):
    print('{nam}({pid}):'.format(nam=self.name, pid=self.pid), end='')
    print(*args, **kwargs)

通过将dict推入队列来发送作业参数。

完成后,我将几个None推入队列,我看到Process-es全部打印出来Received spindown signal.

然而,由于莫名其妙的原因,即使我看到一个进程发出了Received spindown signal消息,他们仍然活着! (也就是说,他们的.is_alive()方法会一直返回True

这是我使用的投票代码:

while len(workers) > 0:
    still_alives = []
    for w in workers:
        if w.is_alive():
            still_alives.append(w)
        else:
            prn('    {nam} trying to join...'.format(nam=w.name))
            w.join()
            prn('    {nam} joined.'.format(nam=w.name))
    prn('  Still alive:', ' '.join((w.name for w in still_alives)))
    workers = still_alives
    time.sleep(10)

这是我看到的输出的摘录:

Main:  Still alive: Querier-0 Querier-2 Querier-3 Querier-4 Querier-6 Querier-7 Querier-9 Querier-10
Querier-9:Received spindown signal.
Querier-4:Received spindown signal.
Main::    Querier-4 trying to join...
Main::    Querier-4 joined.
Main::    Querier-9 trying to join...
Main::    Querier-9 joined.
Main::  Still alive: Querier-0 Querier-2 Querier-3 Querier-6 Querier-7 Querier-10
Querier-3:Received spindown signal.
Querier-10:Received spindown signal.
Querier-6:Received spindown signal.
Main::  Still alive: Querier-0 Querier-2 Querier-3 Querier-6 Querier-7 Querier-10
Main::  Still alive: Querier-0 Querier-2 Querier-3 Querier-6 Querier-7 Querier-10
Querier-0:Received spindown signal.
Main::  Still alive: Querier-0 Querier-2 Querier-3 Querier-6 Querier-7 Querier-10
Main::  Still alive: Querier-0 Querier-2 Querier-3 Querier-6 Querier-7 Querier-10

如您所见,Querier-4-9正常死亡。但Querier-3-10-6-0从未死亡!

这里发生了什么?

1 个答案:

答案 0 :(得分:1)

尝试从两边检查队列;如果它不是空的,则该过程不会终止。

另外,在调试一些多处理问题时,我发现这个link非常方便。