2017-08-14 19 views
2

我使用this answer为了在Linux机器上运行Python中的多处理并行命令。多处理返回“太多打开的文件”,但使用`with ... as`修复它。为什么?

我的代码不喜欢的东西:

import multiprocessing 
import logging 

def cycle(offset): 
    # Do stuff 

def run(): 
    for nprocess in process_per_cycle: 
     logger.info("Start cycle with %d processes", nprocess) 
     offsets = list(range(nprocess)) 
     pool = multiprocessing.Pool(nprocess) 
     pool.map(cycle, offsets) 

但我收到此错误:OSError: [Errno 24] Too many open files
因此,代码是开放太多的文件描述符,即:它已开始过多的进程并没有结束他们。

我固定它与这些线路将最后两行:

with multiprocessing.Pool(nprocess) as pool: 
     pool.map(cycle, offsets) 

但我不知道到底为什么这些线固定它。

with下面发生了什么?

+0

这里是[源代码](https://github.com/python/cpython/blob/master/Lib/multiprocessing/pool.py#L607-L611)每个进程都调用'self.terminate()' – salparadise

+0

'with'版本在'pool.map()'返回后隐式调用'pool.close()'。根据文档,“阻止任何更多任务被提交到池中,一旦所有任务完成,工作进程将退出”。这可能会导致每个任务打开的文件被关闭。 – martineau

+0

我错了,还是@COLDSPEED确实回答了问题,现在它已被删除?我无法深入阅读,但我想...但现在它已经消失......任何人都知道为什么这个问题被低估了? – nephewtom

回答

2

您正在循环中创建新的进程,然后在完成它们后忘记关闭它们。因此,有一点你有太多的开放进程。这是一个坏主意。

您可以通过使用上下文管理器自动调用pool.terminate或自己手动调用pool.terminate来解决此问题。或者,你为什么不在循环外创建一个池一次,然后将任务发送到里面的进程?

pool = multiprocessing.Pool(nprocess) # initialise your pool 
for nprocess in process_per_cycle: 
    ...  
    pool.map(cycle, offsets) # delegate work inside your loop 

pool.close() # shut down the pool 

欲了解更多信息,你可以仔细阅读multiprocessing.Pool文档。

+0

手动调用'pool.terminate'可能是这里要做的事情。 我无法在外面创建池,因为我想在每次迭代时更改它。所以在每一个中,产生的进程的数量都在增加。例如,如果process_per_cycle为[2,4,8],则每次迭代都会产生2,4和8个进程。 – nephewtom

+0

@nephewtom是的,如果你不能使用上下文管理器,那将是另一种选择。 –

+0

虽然为什么用''解决它,但仍然没有答案...... – nephewtom

相关问题