[英]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.