2013-07-07 44 views
1

我從來沒有使用過多處理模塊。python:理解多處理的簡單for循環

有沒有一種方法可以將一個循環做成併發子進程。像

for i in xrange(10): list.append(i) 

而不是順序,使其平行?

我嘗試使用隊列模塊

q = Queue.Queue() 

for i in xrange(10): 
    q.put(i) 


def addto(q): 
    new.append(q.get(block=False)) 


processes = [Process(target=addto, args=(q,))] 
for p in processes: 
    p.start() 
for p in processes: 
    p.join() 

它給出了一個很長的錯誤,即時通訊粘貼它的最後:

C:\WinPython-64bit-2.7.3.3\python-2.7.3.amd64\lib\pickle.pyc in save_global(self, obj, name, pack) 
    746    raise PicklingError(
    747     "Can't pickle %r: it's not found as %s.%s" % 
--> 748     (obj, module, name)) 
    749   else: 
    750    if klass is not obj: 

PicklingError: Can't pickle <type 'thread.lock'>: it's not found as thread.lock 

我也看到這個很多:

processes = [Process(target=func, args=(q,x)) for i in some iterable] 

所以好吧有一個func(q,x)好吧,我有一個map()或者for循環/而進入我的函數func(),那麼爲什麼迭代過程,再一次? 我不想循環使用過程的整個功能,但只是使這些特定的循環並行進程。爲什麼用args迭代目標函數?我的意思是當我已經q.put它?

如果我做

processes = Process(target=addto, args=(q,)).start() 
+0

「我的意思是我什麼時候已經q.put?」究竟!你的例子太微不足道了。即使沒有'q.put()'循環,也沒有足夠的工作來證明它在進程之間分配。 –

+0

@BrianCain我知道這很愚蠢,但我可以用線程來理解它們是如何工作的。我想知道過程如何工作。特別是對我來說問題是使循環平行。 – user2290820

回答

4

Queue.Queue是線程安全的隊列和線程原語不能轉移到其他進程。您需要改爲multiprocessing.Queue;簡單地替換

import Queue 
q = Queue.Queue() 

import multiprocessing 
q = multiprocessing.Queue() 

此外,new必須multiprocessing.managers.list類型。

但是,請注意,您只是複製了multiprocessing.Pool;你可以寫

import multiprocessing 

new = multiprocessing.Manager().list() 
def addto(val): 
    new.append(val) 

pool = multiprocessing.Pool() 
for i in xrange(10): 
    pool.apply_async(addto, (i,)) 
pool.close() 
pool.join() 
print(new) 
+0

偉大的洞察力。我沒有從多重處理進口隊列。可以,不適當更新與那 – user2290820

+0

新發生的事情仍然是空的new = [] – user2290820

+0

@ user2290820更新了一個完整的例子,這對我來說很好(默認情況下,它使用一個進程每個虛擬CPU,因此對於多處理器機器,根據調度情況你甚至會看到不同的結果)。這個例子是否適合你?如果不是,你會得到什麼錯誤信息和輸出? – phihag