以下代码抛出异常并在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,这只是烦人的。 / p>
有没有办法干净地做这个模式?
答案 0 :(得分:0)
我想有几种方法可以做到这一点,但是如果不确切知道它是什么,你就不要去做它很难推荐一个。
我想最简单的就是为此目的使用2个不同的队列。一个用于新来的工人,一个用于成品工人。
答案 1 :(得分: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
对象放入Queue
,这是不允许的,因此错误。
如果你想要一个有用的解决方案,那将有助于澄清你想要实现的目标。
答案 2 :(得分:0)
抱怨的错误是:
p.q.put(p)
在这里,您尝试将引用Queue
的对象放入队列中。队列用于在进程之间进行通信,其工作方式是将您尝试放入其中的任何内容进行腌制,然后在另一个进程中对其进行取消 - 但是不可能腌制Queue
,甚至不能感。
这就是为什么当你尝试挑选一个队列时,你会得到你提到的错误:
>>> 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())
...
有关更多示例,请查看docs