使用多处理时出现以下错误:
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级别的错误。任何人都可以对此有所了解吗?
更新:好的,所以我想出了如何解决这个问题。但我仍然有点困惑。我正在返回这个类的一个实例:
class SpecData(object):
def __init__(self, **kwargs):
self.__dict__.update(**kwargs)
def to_dict(self):
return self.__dict__
如果我返回此对象的实例,则会收到错误。但是,如果我调用to_dict
并返回字典,则可以正常工作。我做错了什么?
答案 0 :(得分:3)
尝试使用pickle
模块而不是cPickle
模块 - pickle
是用纯Python编写的,并且它通常会提供比cPickle
更有用的错误消息。 (虽然有时我不得不求助于制作pickle.py
的本地副本,并在错误位置附近添加一些调试printf语句以找出问题。)
跟踪问题后,您可以切换回cpickle。
(我对多处理模块并不熟悉,所以我不确定你是在做酸洗还是它。如果是,那么最简单的方法就是让它使用泡菜而不是cpickle在导入多处理/线程模块之前要做一些猴子修补:import sys, pickle; sys.modules['cPickle']=pickle
)
答案 1 :(得分:2)
我认为这是一些python函数的可选性/不可克服性的问题。看这篇文章:
http://khinsen.wordpress.com/2012/02/06/teaching-parallel-computing-in-python/
我使用django-celery(使用多处理模块)遇到了类似的问题。如果我的任务代码产生了本身不可伪装的错误,那么这个多进程/ pickle异常会掩盖信息。因为我还没有想出一个更好的方法来传播错误,所以我会在我的任务代码中调试日志记录来追捕它。我应该更聪明地了解我传递到队列中的内容(防止将异常放到消息队列中,因此多进程模块不会尝试对它们进行pickle / unpickle)。
在上述情况下,您可能需要确保SpecData.__dict__
可以设置。见http://docs.python.org/library/pickle.html#pickle-protocol
答案 2 :(得分:0)
我已经在C ++,Java和Delphi中完成了线程安全,但是没有使用Python,所以我的评论很简单。
This page on Python and Thread-Safety特别提到将字典赋值为原子和线程安全的。您对自定义类的引用可能不是线程安全的?如果您仍然宁愿在两个线程之间传递自定义容器类,请尝试添加一些推荐的锁定机制。
我发现其他搜索结果强调Python完全是线程安全的,这令人着迷。 The Python docs themself声明提供了锁和其他机制来帮助使用线程化的应用程序,所以看起来就像是互联网出错了(甚至会发生这种情况?)。