使用多重处理时出现以下错误:
Exception in thread Thread-2:
Traceback (most recent call last):
File "/usr/lib/python2.6/threading.py", line 525, in __bootstrap_inner
self.run()
File "/usr/lib/python2.6/threading.py", line 477, in run
self.__target(*self.__args, **self.__kwargs)
File "/usr/lib/python2.6/multiprocessing/pool.py", line 282, in _handle_results
task = get()
UnpicklingError: NEWOBJ class argument has NULL tp_new
我完全不知道这是什么意思,尽管在C级别听起来有些错误。谁能对此有所启发?
UPDATE:好的,所以我想出了解决方法。但是我还是有点困惑。我要返回此类的一个实例:
class SpecData(object):
def __init__(self, **kwargs):
self.__dict__.update(**kwargs)
def to_dict(self):
return self.__dict__
如果返回此对象的实例,则会收到错误。但是,如果我调用to_dict
并返回字典,则它可以工作。我在做什么错?
尝试使用pickle
模块而不是cPickle
模块- pickle
是用纯Python编写的,并且通常比cPickle
提供更多有用的错误消息。 (尽管有时我不得不求助于制作pickle.py
的本地副本,并在错误位置附近添加一些debug printf语句来找出问题所在。)
一旦找到问题所在,就可以切换回指尖。
(我不太熟悉多处理模块,所以我不确定是在做酸洗还是在做酸洗。如果是这样,那么使它使用酸洗而不是点刺的最简单方法可能是在导入多处理/线程模块之前先进行一些猴子修补:import sys, pickle; sys.modules['cPickle']=pickle
)
我认为这是某些python函数的可拾取性/不可拾取性的问题。看到这篇文章:
http://khinsen.wordpress.com/2012/02/06/teaching-parallel-computing-in-python/
我在使用django-celery(使用多处理模块)时遇到了类似的问题。如果我的任务代码引发错误,而这些错误本身是不可挑剔的,则此多进程/棘手异常会使信息模糊。因为我还没有找到更好的方法来传播错误,所以我求助于调试登录我的任务代码以查找错误。我可能应该对传递到队列中的内容变得更聪明(防止将异常放入消息队列中,因此多进程模块不会尝试腌制/释放它们)。
在上述情况下,您可能需要确保SpecData.__dict__
可腌制。参见http://docs.python.org/library/pickle.html#pickle-protocol
我已经在C ++,Java和Delphi中完成了线程安全性,但在Python中却没有,所以请多加评论。
This page on Python and Thread-Safety特别提到字典的分配是原子的和线程安全的。也许您对自定义类的引用不是线程安全的?如果您仍然希望在两个线程之间传递自定义容器类,请尝试添加一些推荐的锁定机制。
我发现其他搜索结果着重指出Python是完全线程安全的,这一点令人着迷。 The Python docs themself指出提供了锁和其他机制来帮助线程化应用程序,因此看起来好像是Internet错误的情况(甚至会发生吗?)。