簡體   English   中英

具有全局變量的 multiprocessing.Pool

[英]multiprocessing.Pool with a global variable

我正在使用 python 的多處理庫中的池 class 編寫一個將在 HPC 集群上運行的程序。

這是我正在嘗試做的事情的抽象:

def myFunction(x):
    # myObject is a global variable in this case
    return myFunction2(x, myObject)

def myFunction2(x,myObject):
    myObject.modify() # here I am calling some method that changes myObject
    return myObject.f(x)

poolVar = Pool()
argsArray = [ARGS ARRAY GOES HERE]
output = poolVar.map(myFunction, argsArray)

function f(x) 包含在 *.so 文件中,即它正在調用 C function。

我遇到的問題是每次運行程序時 output 變量的值都不同(即使 function myObject.f() 是確定性函數)。 (如果我只有一個進程,那么每次運行程序時 output 變量都是相同的。)

我嘗試創建 object 而不是將其存儲為全局變量:

def myFunction(x):
    myObject = createObject()
    return myFunction2(x, myObject)

但是,在我的程序中,創建 object 的開銷很大,因此,創建一次 myObject 然后在每次調用 myFunction2() 時修改它要容易得多。 因此,我不想每次都創建 object。

你有什么建議嗎? 我對並行編程很陌生,所以我可能會把這一切都搞錯。 我決定使用池 class,因為我想從簡單的開始。 但我願意嘗試更好的方法。

我正在使用 python 的多處理庫中的 Pool 類在 HPC 集群上進行一些共享內存處理

進程不是線程! 不能簡單地將Thread替換為Process並期望所有工作都相同。 Process共享內存,這意味着全局變量被復制,因此它們在原始進程中的值不會改變。

如果要在進程之間使用共享內存,則必須使用multiprocessing的數據類型,例如ValueArray ,或使用Manager創建共享列表等。

特別是您可能對Manager.register方法感興趣,它允許Manager創建共享的自定義對象(盡管它們必須是可拾取的)。

但是我不確定這是否會提高性能。 由於進程之間的任何通信都需要酸洗,而且酸洗通常簡單地實例化對象花費更多的時間。

請注意,您可以在創建Pool時對傳遞initializerinitargs參數的工作進程進行一些初始化。

例如,以最簡單的形式,在工作進程中創建一個全局變量:

def initializer():
    global data
    data = createObject()

用作:

pool = Pool(4, initializer, ())

然后工作函數可以放心地使用data全局變量。


樣式說明:永遠不要為您的變量/模塊使用內置的名稱。 在您的情況下, object是內置的。 否則,您最終會遇到意想不到的錯誤,這些錯誤可能很模糊且難以追蹤。

全局關鍵字僅適用於同一文件。 另一種方法是在池進程初始化程序中動態設置值, somefile.py可以只是一個空文件:

import importlib

def pool_process_init():
    m = importlib.import_module("somefile.py")
    m.my_global_var = "some value"

pool = Pool(4, initializer=pool_process_init)

如何在任務中使用var:

def my_coroutine():
    m = importlib.import_module("somefile.py")
    print(m.my_global_var)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM