0

以下代码在 python 2.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)

这实际上是某种竞争条件,如下所示:

yuv@yuvpad2:~/$ python3.3 t.py
123
Traceback (most recent call last):
  File "/home/yuv/Downloads/Python-3.3.0/Lib/multiprocessing/queues.py", line 249, in _feed
yuv@yuvpad2:~/$ 

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

尽管多线程对我的情况很有效,但我不使用的原因Queue.Queue是因为在 Python 2.7 中存在一个错误,它使 queue.get() 忽略 Ctrl-C,这很烦人。

有没有办法干净地做这个模式?

真正的问题代码在键盘上

4

3 回答 3

1

抱怨的错误是这样的:

p.q.put(p)

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

这就是为什么当您尝试腌制队列时会收到您提到的错误:

>>> from multiprocessing import Queue
>>> q = Queue()
>>> import pickle
>>> pickle.dumps(q)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.2/multiprocessing/queues.py", line 77, in __getstate__
    assert_spawning(self)
  File "/usr/lib/python3.2/multiprocessing/forking.py", line 51, in assert_spawning
    ' through inheritance' % type(self).__name__
RuntimeError: Queue objects should only be shared between processes through inheritance

如果您想使用队列在进程之间共享数据,可以这样做:

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

有关更多示例,您应该查看文档

于 2013-04-25T11:59:47.807 回答
0

我想有几种方法可以做到这一点,但如果不确切知道你不想做什么,很难推荐一种。

我想最简单的方法是为此目的使用 2 个不同的队列。一个用于新来的工人,一个用于完成的工人。

于 2013-04-25T11:49:39.830 回答
0

回溯未在代码中显示问题的原因是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

...我怀疑是由线路发起的...

p.q.put(p)

...您似乎将Pool包含对象的Queue对象放入 aQueue中,这是不允许的,因此出现错误。

如果您想要一个有用的解决方案,这将有助于明确您想要实现的目标。

于 2013-04-25T11:56:38.600 回答