2017-05-03 67 views
0

我試圖避免必須將變量冗餘地傳遞到dataList(例如[(1, globalDict), (2, globalDict), (3, globalDict)]),並在全局範圍內使用它們。然而,在下面的代碼中,global globalDict不是這樣做的解決方案。使用多處理和池時如何訪問全局變量?

有沒有一種直接的方式來訪問全局多處理函數中的數據?

我閱讀以下here

通信是昂貴 相反的線程之間的通信,交換過程之間的數據是昂貴得多在Python,數據被之前酸洗在爲二進制格式。因此,當任務很小時,通信開銷可能非常顯着,爲了減少外部成本,更好地分配塊中的任務。「

我不確定這是否適用於此,但我想在任何情況下簡化數據訪問。

def MPfunction(data): 
    global globalDict 

    data += 1 

    # use globalDict 

    return data 

if __name__ == '__main__': 

    pool = mp.Pool(mp.cpu_count()) 

    try: 
     globalDict = {'data':1} 

     dataList = [0, 1, 2, 3] 
     data = pool.map(MPfunction, dataList, chunksize=10) 

    finally: 
     pool.close() 
     pool.join() 
     pool.terminate() 
+0

Windows中的任何unixy系統這種方式有很大的不同。你使用哪個? – tdelaney

+0

Unix,Python 2.7 – Phillip

回答

4

在Linux上,multiprocessing分叉進程的新副本以運行池worker。該進程具有父內存空間的寫時複製視圖。只要您在創建池之前分配globalDict,它已經在那裏。請注意,該字典的任何更改都留在孩子身上。

在Windows上,創建了一個新的python實例,並且在孩子中醃製/取消了所需的狀態。創建池並在那裏複製時,可以使用初始化函數。這是每個子進程的一個副本,比每個映射的項目要好一次。

(順便說一句,啓動try塊創建池後,這樣你就沒有引用一個壞池對象,如果這就是引發錯誤)

import platform 

def MPfunction(data): 
    global globalDict 

    data += 1 

    # use globalDict 

    return data 

if platform.system() == "Windows": 
    def init_pool(the_dict): 
     global globalDict 
     globalDict = the_dict 

if __name__ == '__main__': 
    globalDict = {'data':1} 

    if platform.system() == "Windows": 
     pool = mp.Pool(mp.cpu_count, init_pool(globalDict)) 
    else: 
     pool = mp.Pool(mp.cpu_count()) 

    try: 
     dataList = [0, 1, 2, 3] 
     data = pool.map(MPfunction, dataList, chunksize=10) 
    finally: 
     pool.close() 
     pool.join() 
+0

當'def MPfunction(data):'在另一個模塊中時,它也可以工作嗎?我試過了,全局變量沒有定義...? – Gabriel