2013-04-25 19 views
0

以下代碼將引發異常並在Python 2.7和3.3中打印123。將multiprocessing.Queue放入多處理器.Queue爆炸

from multiprocessing import Queue 

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

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

它實際上是某種形式的競爭條件的可以在這裏看到:

[email protected]:~/$ 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 
[email protected]:~/$ 

完整的錯誤是RuntimeError: Queue objects should only be shared between processes through inheritance和回溯完全不解釋如何/它發生在哪裏。問題的根源在於隊列中的對象無法引用隊列。我的真實用例實際上是一個工作對象和一個池對象,在這裏工作人員報告它完成了對池的Queue的工作。所以我希望工人把自己送回工人Queue

我沒有使用Queue.Queue的原因,雖然多線程對我的情況很好,但是因爲在Python 2.7中有一個錯誤讓queue.get()忽略了Ctrl-C,這只是令人討厭的。

有沒有辦法乾淨地做這個模式?

The real problem code is on codepad

回答

0

我想有幾個方法可以做到這一點,但不知道到底什麼是你wan't做很難推薦一個。

我想最簡單的一個會使用2個不同的隊列來達到這個目的。一個爲新來的工人,一個爲完工的工人。

+0

我不知道怎麼有2個隊列會有所幫助。即我想排隊一個可以添加東西到隊列的對象。 (請參閱鍵盤上的代碼) – ubershmekel 2013-04-25 12:53:55

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中,這是不允許的,因此是錯誤。

如果你想要一個有用的解決方案,這將有助於澄清你想要達到的目標。

+0

我添加了代碼片段http://codepad.org/JX0lDoeG – ubershmekel 2013-04-25 12:51:41

0

什麼錯誤complainig大約是這樣的:

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