Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/283.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 检索使用multiprocessing.Pool.map启动的进程的退出代码_Python_Multiprocessing - Fatal编程技术网

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

Python 检索使用multiprocessing.Pool.map启动的进程的退出代码,python,multiprocessing,Python,Multiprocessing,我正在使用python多处理模块来并行化一些计算量大的任务。 显而易见的选择是使用员工池,然后使用映射方法 然而,进程可能会失败。例如,它们可能会被oom杀手悄悄杀死。因此,我希望能够检索使用map启动的进程的退出代码 此外,出于日志记录的目的,我希望能够知道为执行iterable中的每个值而启动的进程的PID。如果您使用的是multiprocessing.Pool.map您通常对池中子进程的退出代码不感兴趣,您感兴趣的是他们从工作项返回的值。这是因为在正常情况下,池中的进程在关闭/加入池之前不

我正在使用python
多处理模块来并行化一些计算量大的任务。
显而易见的选择是使用
员工池
,然后使用
映射
方法

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


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

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

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

也就是说,您可以通过使用private
\u pool
属性直接访问池中的
多处理.process
对象来获取池中每个进程的pid:

pool = multiprocessing.Pool()
for proc in pool._pool:
  print proc.pid
因此,您可以尝试检测进程何时意外死亡(假设您没有因此陷入阻塞调用中)。您可以通过在调用
map\u async
前后检查池中的进程列表来完成此操作:

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.
我们必须制作列表的副本,因为当
池中的一个进程死亡时,Python会立即用一个新进程替换它,并从列表中删除死亡的进程


这在我的测试中是有效的,但是因为它依赖于
对象(
\u池
)的私有属性,所以在生产代码中使用它是有风险的。我还建议,过分担心这种情况可能有点过头了,因为这种情况不太可能发生,而且会使实现大大复杂化。

您是使用Python2还是Python3?我主要使用Python2。您是对的:当出现这种问题时,我会得到奇怪的结果。在当前代码中,进程由一个特殊的循环启动。我的想法是用一个(更简单的)map调用来代替这个循环。但是,您的解决方案与当前的解决方案一样复杂,因此我认为它不值得。另外,进程将其结果写入磁盘(因此我并不真正需要它们的结果)。不过,您的回答很有趣。这里还需要注意:检测进程何时意外终止,并在任何未完成的任务发生时引发
BrokenProcessPool
。有一个文件反对
多处理
,它有一个工作补丁,将此行为添加到
多处理.Pool
中。台球是一个多处理叉,似乎可以处理这个案例@JAR.JAR.beans!非常感谢您…我一直都有关于死亡进程的问题,我一直在寻找一种方法来获取关于死亡进程的更多信息:这个模块很好地完成了这个任务。同时,我提出了一个Python问题,因为我认为这需要在标准库代码中解决: