把多处理队列在一个多处理队列爆炸

2024-04-24 21:58:20 发布

您现在位置:Python中文网/ 问答频道 /正文

下面的代码抛出一个异常并在python2.7和3.3中打印123。在

from multiprocessing import Queue

class Pool(object):
    def __init__(self):
        self.q = Queue()

p = Pool()
p.q.put(p)
print(123)

这实际上是某种竞赛状态,从这里可以看出:

^{pr2}$

完整的错误是RuntimeError: Queue objects should only be shared between processes through inheritance,而回溯根本没有解释它是如何/在哪里发生的。问题的根源是队列中的对象不能引用队列。我真正的用例实际上是一个worker对象和一个pool对象,其中worker向池的Queue报告它完成了工作。所以我希望worker将自己发送回worker Queue。在

我之所以不使用Queue.Queue,虽然多线程处理在我的情况下是很好的,因为在Python2.7中有一个bug队列.get()忽略Ctrl-C,这很烦人。在

有没有办法把这个图案弄得干干净净?在

The real problem code is on codepad


Tags: 对象代码fromimportselfobject队列queue
3条回答

回溯没有在代码中显示问题的原因是multiprocessing.Queue类启动了一个后台线程,并且在该线程中生成了异常。我得到以下回溯。。。在

Traceback (most recent call last):
  File "/usr/lib/python2.7/multiprocessing/queues.py", line 266, in _feed
    send(obj)
  File "/usr/lib/python2.7/multiprocessing/queues.py", line 77, in __getstate__
    assert_spawning(self)
  File "/usr/lib/python2.7/multiprocessing/forking.py", line 51, in assert_spawning
    ' through inheritance' % type(self).__name__
RuntimeError: Queue objects should only be shared between processes through inheritance

…我怀疑是线路引起的。。。在

^{pr2}$

…其中似乎要将包含Queue对象的Pool对象放入Queue中,这是不允许的,因此会出现错误。在

如果你想要一个有用的解决方案,这将有助于明确你想要达到的目标。在

我想有几种方法可以做到这一点,但如果不知道具体是什么你不应该做,很难推荐一种。在

我想最简单的方法是使用两个不同的队列来实现这个目的。一个给新来的工人,一个给成品工人。在

错误在于:

p.q.put(p)

这里您尝试将引用Queue的对象放入队列中。队列用于进程之间的通信,其工作方式是将您试图放入其中的任何内容进行pickle,然后在另一个进程中取消pickle,但是pickle a Queue是不可能的,甚至没有意义。在

这就是为什么当您尝试对队列进行pickle时,会出现您提到的错误:

^{pr2}$

如果要使用队列在进程之间共享数据,有一种方法是这样做的:

class Worker(multiprocessing.Process):
    queue = multiprocessing.Queue()
    def run(self):
        print(self.queue.get())
        ...

有关更多示例,请检查docs

相关问题 更多 >