繁体   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