在Python多进程中查找异常

6

我有一段类似于以下Python代码:

procs = cpu_count()-1
if serial or procs == 1:
    results = map(do_experiment, experiments)
else:
    pool = Pool(processes=procs)     
    results = pool.map(do_experiment, experiments)

当我设置 serial 标志时,它运行良好,但是在使用 Pool 时会出现以下错误。 当我尝试从 do_experiment 打印一些东西时,没有任何显示,因此我无法在那里尝试/捕获并打印堆栈跟踪。

Exception in thread Thread-2:
Traceback (most recent call last):
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 530, in __bootstrap_inner
    self.run()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 483, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/pool.py", line 285, in _handle_tasks
    put(task)
TypeError: 'NoneType' object is not callable

什么是处理调试的好方法?

这可能并不重要,但是 cpu_count() 的返回值是什么? - mgilson
取决于系统。我的笔记本电脑上有2个,服务器上有8个。无论哪种方式,如果使用pool.map代替map,事情都会出错。 - noio
1个回答

17

我回溯了我的git历史记录,直到找到一个仍然正常工作的提交。

我在代码中添加了一个继承自dict的类,以便使用.来访问键(例如dict.foo而不是dict["foo"])。然而,多进程并发处理对此不太友好,使用普通的字典解决了这个问题。


1
作为一条注释,你真的不必这样做。使用普通类,然后执行 self.__dict__.update(<带有额外参数的字典>) 即可。 - Voo
1
哇,巧合的是,我添加了完全相同类型的类,也破坏了我的多进程。 - Ryan
这听起来非常意外。你有什么想法这个 bug 的根本原因可能是什么吗?这是 Python 解释器中的一个 bug 吗? - Craig McQueen
也许它会破坏原子访问,从而导致死锁? - DevPlayer
2
当我实现了一些用户可以控制的自然类属性特性时,通过定义“__getattr__”方法,我遇到了同样的错误,这种方式最终导致了“NoneType”异常,而在我删除该方法后,错误消失了。我猜原因是打破了类的正常pickle方式。 - Tong

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接