multiprocessing.Pool与全局变量

时间:2013-09-13 04:12:59

标签: 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)

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

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

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

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

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

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

1 个答案:

答案 0 :(得分:13)

  

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

进程不是主题! 只能将Thread替换为Process,并希望所有内容都能正常工作。 Process es 共享内存,这意味着全局变量已复制,因此它们在原始流程中的值不会发生变化。

如果要在进程之间使用共享内存,则必须使用multiprocessing的数据类型,例如ValueArray,或使用Manager创建共享列表等。

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

但是我不确定这是否会改善性能。由于进程之间的任何通信需要进行酸洗,并且酸洗通常需要更多时间,然后简单地实例化对象。

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

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

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

用作:

pool = Pool(4, initializer, ())

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


样式注释:从不使用变量/模块的内置名称。在您的情况下,object是内置的。否则,你最终会出现意想不到的错误,这些错误可能会模糊不清,难以追踪。