Python的多处理池挂在加入?(Python multiprocessing pool hangs

2019-07-21 05:52发布

我想在平行的几个文件运行一些Python代码。 该结构基本上是:

def process_file(filename, foo, bar, baz=biz):
    # do stuff that may fail and cause exception

if __name__ == '__main__':
    # setup code setting parameters foo, bar, and biz

    psize = multiprocessing.cpu_count()*2
    pool = multiprocessing.Pool(processes=psize)

    map(lambda x: pool.apply_async(process_file, (x, foo, bar), dict(baz=biz)), sys.argv[1:])
    pool.close()
    pool.join()

我以前用过pool.map做同样的事情,它的工作很好,但我似乎无法使用,这里因为pool.map没有(出现)让我在额外的参数传递(和使用lambda来做到这一点不会工作,因为拉姆达不能被整理)。

所以,现在我想要得到的东西()直接使用apply_async工作。 我的问题是,代码似乎挂起,永远不会退出。 几个文件的失败,一个例外,但我不明白为什么什么会导致加盟失败/挂机? 有趣的是,如果没有这些文件的失败,一个例外,它退出干净。

我在想什么?

编辑:当函数(因而工人)失败,我看到这个异常:

Exception in thread Thread-3:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 552, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.7/threading.py", line 505, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/usr/lib/python2.7/multiprocessing/pool.py", line 376, in _handle_results
    task = get()
TypeError: ('__init__() takes at least 3 arguments (1 given)', <class 'subprocess.CalledProcessError'>, ())

如果我看到的这些连一个,过程父进程挂起永远,永远收获着孩子们和退出。

Answer 1:

对不起,回答我的问题,但我发现至少有一个解决办法,以便万一别人也有类似的问题,我想在这里发布。 我会接受任何更好的答案在那里。

我认为,问题的根源是http://bugs.python.org/issue9400 。 这告诉我两件事情:

  • 我没疯,我想要做的真的应该工作
  • 至少在python2,这是泡菜“例外”回父进程非常困难的,如果不是不可能的。 那些简单的工作,但也有很多人。

就我而言,我的工人函数推出这是一个段错误子。 这回CalledProcessError异常,这是不是与pickle。 出于某种原因,这使得在父池对象出去吃午饭,而不是从调用返回join()方法。

在我的具体情况,我不在乎什么例外。 在我最想记录它,继续前进。 要做到这一点,我简单/换我顶工人功能一试除外条款。 如果工人抛出任何异常,它试图返回到父进程,记录之前抓住了,然后工作进程正常退出,因为它不再试图通过发送例外。 见下文:

def process_file_wrapped(filenamen, foo, bar, baz=biz):
    try:
        process_file(filename, foo, bar, baz=biz)
    except:
        print('%s: %s' % (filename, traceback.format_exc()))

然后,我有我的初始映射函数调用process_file_wrapped(),而不是原来的一个。 现在,我的代码按预期工作。



Answer 2:

实际上,你可以使用一个functools.partial ,而不是一个实例lambda在情况下,对象需要进行酸洗。 partial对象是与pickle因为Python 2.7(和在Python 3)。

pool.map(functools.partial(process_file, x, foo, bar, baz=biz), sys.argv[1:])


Answer 3:

对于它的价值,我也有类似的bug(不一样),当pool.map挂。 使用的情况下允许我使用pool.terminate解决它(确保你确实还有改变的东西前)。

我用pool.map调用之前terminate ,所以我知道一切都完了,从文档 :

地图()内置函数的并联等效的(它仅支持一个可迭代虽然参数)。 它会阻止,直到结果准备好了。

如果这是你的使用情况,这可能是一种方法来修补它。



文章来源: Python multiprocessing pool hangs at join?