2011-12-24 79 views
3

我試圖啓動6個線程,每個從列表文件中取出一個項目,將其刪除,然後打印值。使用Python pool.map讓多個進程在列表上執行操作

from multiprocessing import Pool 

files = ['a','b','c','d','e','f'] 

def convert(file): 
    process_file = files.pop() 
    print process_file 

if __name__ == '__main__': 

    pool = Pool(processes=6) 
    pool.map(convert,range(6)) 

預期輸出應該是:

a 
b 
c 
d 
e 
f 

相反,輸出是:

f 
f 
f 
f 
f 
f 

這是怎麼回事?提前致謝。

回答

4

問題的部分原因是您沒有處理池的多進程特性(請注意,在Python中,由於全局解釋器鎖,MultiThreading不能獲得性能)。

是否有原因需要更改原始列表?您當前的代碼不使用傳入的迭代器,而是編輯共享的可變對象,這在併發領域是危險的。一個簡單的解決辦法如下:

from multiprocessing import Pool 

files = ['a','b','c','d','e','f'] 

def convert(aFile): 
    print aFile 

if __name__ == '__main__': 

    pool = Pool() #note the default will use the optimal number of workers 
    pool.map(convert,files) 

你的問題真讓我思考,所以我做了一些更多的探索理解,爲什麼Python中這樣的行爲。看起來,Python正在做一些有趣的黑魔法和深刻複製(同時保持id,這是非標準的)對象到新進程中。這可以通過改變所使用的數或過程中可以看出:

from multiprocessing import Pool 

files = ['d','e','f','a','b','c',] 

a = sorted(files) 
def convert(_): 
    print a == files 
    files.sort() 
    #print id(files) #note this is the same for every process, which is interesting 

if __name__ == '__main__': 

    pool = Pool(processes=1) # 
    pool.map(convert,range(6)) 

==>所有,但在第一次調用打印「真」如預期。

如果將數量或進程設置爲2,則它不太確定,因爲它取決於哪個進程首先實際執行其語句。

+0

這正是我所期待的。感謝您幫助我理解Pool.map函數。 – ensnare 2011-12-24 18:57:45

相關問題