3

使用多处理时出现以下错误:

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并返回字典,它就可以工作。我究竟做错了什么?

4

3 回答 3

3

尝试使用pickle模块而不是cPickle模块——pickle它是用纯 Python 编写的,并且通常它提供的错误消息比cPickle. (虽然有时我不得不求助于制作 的本地副本pickle.py,并在错误位置附近添加一些调试 printf 语句来找出问题。)

找到问题后,您可以切换回 cpickle。

(我对多处理模块不太熟悉,所以我不确定你是在做酸洗还是它。如果是,那么让它使用 pickle 而不是 cpickle 的最简单方法可能是做在导入多处理/线程模块之前进行一些猴子修补import sys, pickle; sys.modules['cPickle']=pickle:)

于 2009-12-30T16:22:06.097 回答
2

我认为这是一些 python 函数的可挑选性/不可挑选性的问题。看到这个帖子:

http://khinsen.wordpress.com/2012/02/06/teaching-parallel-computing-in-python/

我在使用 django-celery(它使用多处理模块)时遇到了类似的问题。如果我的任务代码抛出本身不可挑选的错误,则此多进程/pickle 异常会掩盖信息。因为我还没有找到更好的方法来传播错误,所以我求助于在我的任务代码中调试日志记录来寻找它。我可能应该更聪明地了解我传递到队列的内容(防止将异常放入消息队列,因此多进程模块不会尝试腌制/取消腌制它们)。

在上述情况下,您可能需要确保SpecData.__dict__是可腌制的。请参阅http://docs.python.org/library/pickle.html#pickle-protocol

于 2012-10-22T23:35:05.817 回答
0

我已经在 C++、Java 和 Delphi 中完成了线程安全,但没有在 Python 中完成,所以请对我的评论持保留态度。

这个关于 Python 和线程安全的页面特别提到了将字典分配为原子和线程安全的。也许您对自定义类的引用不是线程安全的?如果您仍希望在两个线程之间传递自定义容器类,请尝试添加一些推荐的锁定机制。

我发现其他搜索结果强调 Python 是完全线程安全的,这很有趣。 Python 文档本身声明提供了锁和其他机制来帮助线程化应用程序,所以看起来这是互联网错误的情况(这甚至发生了吗??)。

关于 python 和线程安全的另一个 StackOverflow 问题

于 2009-12-23T15:22:42.633 回答