2016-08-23 71 views
0

我在多處理中遇到了一個奇怪的行爲。多進程不會看到全局變量?

當我嘗試在從多處理調用的函數中使用全局變量時,它看不到全局變量。

例子:

import multiprocessing 

def func(useless_variable): 
    print(variable) 

useless_list = [1,2,3,4,5,6] 
p = multiprocessing.Pool(processes=multiprocessing.cpu_count()) 
variable = "asd" 

func(useless_list) 

for x in p.imap_unordered(func, useless_list): 
    pass 

輸出:

asd 
multiprocessing.pool.RemoteTraceback: 
""" 
Traceback (most recent call last): 
    File "/usr/lib/python3.4/multiprocessing/pool.py", line 119, in worker 
    result = (True, func(*args, **kwds)) 
    File "pywork/asd.py", line 4, in func 
    print(variable) 
NameError: name 'variable' is not defined 
""" 

The above exception was the direct cause of the following exception: 

Traceback (most recent call last): 
    File "pywork/asd.py", line 11, in <module> 
    for x in p.imap_unordered(func, useless_list): 
    File "/usr/lib/python3.4/multiprocessing/pool.py", line 689, in next 
    raise value 
NameError: name 'variable' is not defined 

正如你看到的,我第一次只是簡單地調用func其打印asd預期。但是,當我用多處理函數調用相同的函數時,它說變量variable不存在,即使在我明確地將它打印之前。

多處理忽略全局變量嗎?我怎樣才能解決這個問題?

回答

1

multiprocessingPool在創建Pool時,它的工作進程分叉(或產生了一種意圖在Windows上模擬分叉的方式)。 fork ing將父內存映射爲孩子時的寫入時拷貝,但它不會在它們之間建立持久聯繫;在fork之後,在父項中進行的更改在子項中不可見,反之亦然。在創建Pool之後,您不能使用任何定義的變量,並且創建Pool之前對變量所做的更改不會反映在工作人員中。

通常,使用Pool,您希望完全避免可變全局狀態;將所有需要的數據傳遞給函數imap -ing(或其他)作爲參數(它們被序列化併發送給子代,所以狀態是正確的),並且具有函數return任何新數據而不是變異全局變量,它將其序列化並將其發送回父進程以便按照它認爲合適的方式使用。

Managers s是一個選項,但通常不是Pool s的正確選項;您通常想要堅持只從僅創建Pool之前只讀全局變量的工作人員,或者使用參數並返回新值,而不使用全局狀態。