2012-11-30 72 views
5

我在我的項目中使用多處理。我有一個將結果放入隊列的工作函數。一切正常。但隨着x的大小增加(在我的情況下,x是一個數組)出了問題。這裏是我的代碼的簡化版本:Python中的多處理被阻止

def do_work(queue, x): 
    result = heavy_computation_function(x) 
    queue.put(result) # PROBLEM HERE 

def parallel_something(): 
    queue = Queue() 
    procs = [Process(target=do_work, args=i) for i in xrange(20)] 
    for p in procs: p.start() 
    for p in procs: p.join() 

    results = [] 
    while not queue.empty(): 
     results.append(queue.get) 

    return results 

我在系統中看到監控蟒蛇流程工作,但隨後事情發生,所有進程都在運行,但什麼都不做。這是我輸入ctrl-D時得到的結果。

pid, sts = os.waitpid(self.pid, flag) 
KeyboardInterrupt 

我做了一些測試。如果我不把結果放在一切正常的地方,那麼這個問題看起來好像是把結果放在隊列中,但那樣就沒有用處。

+4

您似乎從不將隊列對象傳遞給新進程。 'Process'的'args'應該是'tuple'。嘗試將其更改爲'args =(queue,i)'。你的'queue.get'也需要一些括號,以便它成爲'queue.get()'。 – Wessie

回答

3

好吧,它看起來像是在Python的隊列模塊中的一些錯誤。事實上使用..

from multiprocessing import Manager 

queue = Manager().Queue() 

..everything的作品,但我仍然不知道爲什麼.. :)

+0

區別在於你正在實例化'Manager()。Queue()'而不是簡單的'Queue()'。我認爲這意味着'Manager .__ init __()'在第一個表單中被調用,但不在第二個表單中。 – Patrick

5

你最有可能產生死鎖。

programming guidelines

這意味着,無論你使用一個隊列,你需要確保在加入過程之前已放入隊列中的所有項目最終將被刪除。否則,您無法確定將項目放入隊列的進程將終止。還要記住,非守護進程會自動加入。

頁面中還提出了一種可能的修復方法。請記住,如果流程沒有加入,這並不意味着它們在任何意義上「佔領」資源。這意味着您可以在流程完成其操作後(可能使用locks)並在稍後加入流程時將排隊的數據取出。