multiprocessing.Pool与全局变量

Hug*_*dal 9 python multiprocessing

我正在使用python的多处理库中的Pool类编写一个将在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)
Run Code Online (Sandbox Code Playgroud)

函数f(x)包含在*.so文件中,即它调用C函数.

我遇到的问题是每次运行程序时输出变量的值都不同(即使函数myObject.f()是确定性函数).(如果我只有一个进程,那么每次运行程序时输出变量都是相同的.)

我试过创建对象而不是将其存储为全局变量:

def myFunction(x):
    myObject = createObject()
    return myFunction2(x, myObject)
Run Code Online (Sandbox Code Playgroud)

但是,在我的程序中,对象创建很昂贵,因此,每次调用myFunction2()时,创建myObject一次然后修改它会容易得多.因此,我不想每次都创建对象.

你有什么建议吗?我是并行编程的新手,所以我可能会把这一切都搞错了.我决定使用Pool类,因为我想从简单的东西开始.但我愿意尝试更好的方法.

Bak*_*riu 17

我正在使用python的多处理库中的Pool类在HPC集群上进行一些共享内存处理.

进程不是线程!不能简单地替换ThreadProcess,并希望所有的工作一样.Processes 共享内存,这意味着全局变量被复制,因此它们在原始进程中的值不会改变.

如果你想使用进程间共享内存,那么你必须使用multiprocessing的数据类型,例如Value,Array或使用Manager创建共享列表等.

特别是您可能对该Manager.register方法感兴趣,该方法允许Manager创建共享自定义对象(尽管它们必须是可选择的).

但是我不确定这是否会改善性能.由于进程之间的任何通信都需要进行酸洗,并且酸洗通常需要更多时间,因此只需实例化对象即可.

请注意,在创建时,可以对传递initializerinitargs参数的工作进程进行一些初始化Pool.

例如,以最简单的形式,在工作进程中创建一个全局变量:

def initializer():
    global data
    data = createObject()
Run Code Online (Sandbox Code Playgroud)

用作:

pool = Pool(4, initializer, ())
Run Code Online (Sandbox Code Playgroud)

然后worker函数可以使用data全局变量而无需担心.


样式说明:切勿将变量/模块的内置名称用于变量/模块.在你的情况下object是一个内置的.否则你最终会出现意想不到的错误,这些错误可能很难以追查.

  • 我尝试了你的解决方案,但它没有用.我还有同样的问题. (5认同)