Python多处理池挂在连接处?

clemej:

我正在尝试在多个文件上并行运行一些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来这样做是行不通的,因为无法将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'>, ())

如果我什至看到其中之一,则进程父进程将永远挂起,永远不会收获子进程并退出。

clemej:

抱歉回答我自己的问题,但是我至少找到了一种解决方法,以防万一其他人遇到类似的问题,我想在这里发布。我会接受任何更好的答案。

我相信问题的根源是http://bugs.python.org/issue9400这告诉我两件事:

  • 我并不疯狂,我真正想做的应该是可行的
  • 至少在python2中,很难甚至不可能将“例外”腌制回父进程。简单的方法可以工作,而其他许多方法则不能。

就我而言,我的工作人员功能正在启动一个存在段错误的子流程。返回的CalledProcessError异常是不可腌制的。由于某些原因,这会使父对象中的pool对象外出吃午餐,而不是从对join()的调用中返回。

在我的特定情况下,我不在乎异常是什么。最多我想记录下来并继续前进。为此,我只需将我的顶级worker函数包装在try / except子句中。如果工作程序引发任何异常,则在尝试返回到父进程之前将其捕获并记录下来,然后该工作进程将正常退出,因为它不再尝试通过其发送异常。见下文:

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()而不是原始的函数。现在我的代码按预期工作。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章