![](/img/trans.png)
[英]Python multiprocessing pool.map hangs after sklearn function call
[英]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.