[英]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
的數據類型,例如Value
、 Array
,或使用Manager
創建共享列表等。
特別是您可能對Manager.register
方法感興趣,它允許Manager
創建共享的自定義對象(盡管它們必須是可拾取的)。
但是我不確定這是否會提高性能。 由於進程之間的任何通信都需要酸洗,而且酸洗通常比簡單地實例化對象花費更多的時間。
請注意,您可以在創建Pool
時對傳遞initializer
和initargs
參數的工作進程進行一些初始化。
例如,以最簡單的形式,在工作進程中創建一個全局變量:
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.