首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >检索用multiprocessing.Pool.map启动的进程的退出代码

检索用multiprocessing.Pool.map启动的进程的退出代码
EN

Stack Overflow用户
提问于 2014-06-24 20:58:26
回答 1查看 8.5K关注 0票数 9

我使用python multiprocessing模块并行处理一些计算繁重的任务。最明显的选择是使用工人的Pool,然后使用map方法。

然而,进程可能会失败。例如,它们可能会被静默地杀死,例如被oom-killer杀死。因此,我希望能够检索使用map启动的进程的退出代码。

此外,出于日志记录的目的,我希望能够知道启动的进程的PID值,以执行迭代中的每个值。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-06-24 21:29:33

如果您使用的是multiprocessing.Pool.map,您通常对池中子进程的退出代码不感兴趣,您感兴趣的是它们从工作项返回的值。这是因为在正常情况下,Pool中的进程只有在close/join池中才会退出,因此在所有工作完成之前没有要检索的退出代码,并且Pool即将被销毁。正因为如此,没有公共API来获取这些子进程的退出代码。

现在,你担心的是一些特殊的情况,在它工作的时候,一些超带的东西杀死了其中一个子进程。如果你遇到这样的问题,你可能会遇到一些奇怪的行为。事实上,在我的测试中,当Pool作为map调用的一部分工作时,它杀死了一个进程,但map从未完成,因为被杀死的进程没有完成。然而,Python确实立即启动了一个新的进程来取代我杀死的那个进程。

也就是说,您可以使用私有的multiprocessing.Process属性直接访问池中的_pool对象,从而获得池中每个进程的pid:

代码语言:javascript
复制
pool = multiprocessing.Pool()
for proc in pool._pool:
  print proc.pid

因此,您可以做一件事来尝试检测某个进程何时意外死亡(假设您不会因此陷入阻塞调用中)。您可以在调用map_async之前和之后检查池中的进程列表。

代码语言:javascript
复制
before = pool._pool[:]  # Make a copy of the list of Process objects in our pool
result = pool.map_async(func, iterable)  # Use map_async so we don't get stuck.
while not result.ready():  # Wait for the call to complete
    if any(proc.exitcode for proc in before):  # Abort if one of our original processes is dead.
        print "One of our processes has exited. Something probably went horribly wrong."
        break
    result.wait(timeout=1)
else:  # We'll enter this block if we don't reach `break` above.
    print result.get() # Actually fetch the result list here.

我们必须创建列表的副本,因为当Pool中的进程死亡时,Python立即用新进程替换它,并从列表中删除已死的进程。

这在我的测试中适用,但是由于它依赖于Pool对象(_pool)的私有属性,所以在生产代码中使用它是有风险的。我还建议,过于担心这种情况可能会造成过度的后果,因为这种情况不太可能发生,而且会使实现变得复杂。

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24396147

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档