2012-03-28 30 views
10

我想調用多個進程的函數。顯而易見的解決方案是python的multiprocessing模塊。問題是該功能有副作用。它創建一個臨時文件並使用atexit.register和全局列表註冊要在退出時刪除的文件。以下應該說明問題(在不同的上下文中)。蟒蛇並行地圖(multiprocessing.Pool.map)與全球數據

import multiprocessing as multi 

glob_data=[] 
def func(a): 
    glob_data.append(a) 

map(func,range(10)) 
print glob_data #[0,1,2,3,4 ... , 9] Good. 

p=multi.Pool(processes=8) 
p.map(func,range(80)) 

print glob_data #[0,1,2,3,4, ... , 9] Bad, glob_data wasn't updated. 

有沒有辦法讓全球數據更新?

請注意,如果您嘗試使用上述腳本,則可能不應該使用交互式解釋器,因爲multiprocessing要求模塊__main__可由子進程導入。

UPDATE

添加在FUNC的global關鍵字不會幫助 - 例如:

def func(a): #Still doesn't work. 
    global glob_data 
    glob_data.append(a) 

回答

18

你需要一個列表(glob_data)通過共享內存的支持,多重的經理給你這一點:

import multiprocessing as multi 
from multiprocessing import Manager 

manager = Manager() 

glob_data= manager.list([]) 

def func(a): 
    glob_data.append(a) 

map(func,range(10)) 
print glob_data #[0,1,2,3,4 ... , 9] Good. 

p=multi.Pool(processes=8) 
p.map(func,range(80)) 

print glob_data # Super Good. 

對於一些背景(搜索經理):

http://docs.python.org/library/multiprocessing.html

+1

Cheers,這個作品完美無缺爲了我。我應該在這裏提到它的工作原理,因爲我追加到glob_data的對象是不可變的(在我的實際應用程序中,示例中爲整數)。如果它們被包裝到列表中的對象是可變的,那麼如果它們被改變,則必須小心重新將它們添加到列表中。 – mgilson 2012-03-28 19:07:38

+0

在您的服務:) – 2012-03-29 22:50:04

+0

@RafaelFerreira運作良好!但結果不一致,就像我的情況一樣..我正在使用manager.dict(),每次運行我的代碼時都會更改值。我看到應該應用鎖定,但不確定。 – 2016-05-16 06:05:02

1

有FUNC返回你從處理想的結果的元組和你想要的東西附加到glob_data。然後,當p.map完成時,您可以從返回的元組中提取第一個元素的結果,並且可以從第二個元素生成glob_data。

+0

呀,我想過......我的用例比這個更復雜一點。我想刪除的臨時文件被深埋在類內部,因爲它們只是臨時文件,所以我更願意將它們和它們的名稱作爲類API的專用部分(Implementation detail)。 – mgilson 2012-03-28 16:43:51