繁体   English   中英

Pool.map在4次迭代后挂起

[英]Pool.map hangs after 4 iterations

我是Python和多重处理的新手。 我想批量转换一堆文件,所以我想尝试多处理。 Pool和map()概念似乎很简单,但似乎不起作用。 我将其简化为下面的测试程序,但要点是:它将进行4次迭代(Pool中每个进程),然后挂起。 这是测试代码:

import multiprocessing, logging
import os
import sys

mpl = multiprocessing.log_to_stderr()
mpl.setLevel(logging.INFO)

def chill(t):
    cmd  = '/bin/sleep'
    args = (cmd,str(t))
    print >>sys.stderr, os.getpid(), args
    os.execv(cmd, args)

if __name__ == "__main__" :
    times = [ 1 ] * 100
    pool = multiprocessing.Pool(1)  # change this for more processes
    pool.map(chill, times)
    pool.close()
    pool.join()

当我运行它时,它在第4次迭代后挂起。 进程数量的增加只会使其挂在进程数量的4倍。 这个“ 4”的神奇之处是什么,我在做什么错?

问题是os.execv替换了子进程,因此父子进程之间的常规握手丢失了。 Pool.map()发送要分块处理的参数。 如果该进程意外退出,则mp重新启动该进程并发送另一个块。 您可能已经在多处理模块中发现了一个错误,因为它会继续发送数据以在这种异常情况下进行处理,然后挂起以等待永远不会到达的任务完成。

解决方案是使用诸如subprocess.call的功能对要运行的代码进行完整的分叉和执行。 这使子进程保持完好无损,并且能够将结果传递回父进程。

通过对测试程序进行一些更改,可以更清楚地看到该问题。

import multiprocessing, logging
import os
import sys
import subprocess as subp

mpl = multiprocessing.log_to_stderr()
mpl.setLevel(logging.INFO)

def chill(args):
    i, t = args
    cmd  = '/bin/sleep'
    args = (cmd,str(t))
    print >>sys.stderr, i, os.getpid(), args
    os.execv(cmd, args)
#    subp.call(['/bin/sleep', str(t)])

if __name__ == "__main__" :
    times = [(i,1) for i in range(100)]
    pool = multiprocessing.Pool(1)  # change this for more processes
    pool.map(chill, times)
    pool.close()
    pool.join()

地图将作品分成4个块,然后在最后一个块之后挂起

[INFO/PoolWorker-1] child process calling self.run()
0 9204 ('/bin/sleep', '1')
[INFO/PoolWorker-2] child process calling self.run()
25 9208 ('/bin/sleep', '1')
[INFO/PoolWorker-3] child process calling self.run()
50 9209 ('/bin/sleep', '1')
[INFO/PoolWorker-4] child process calling self.run()
75 9210 ('/bin/sleep', '1')
[INFO/PoolWorker-5] child process calling self.run()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM