在循环中使用multiprocessing.pool并更新目标函数

时间:2017-11-20 23:07:20

标签: python python-multiprocessing

我有一个关于python Multiprocessing.pool的快速问题。这是我的代码:

import multiprocessing as mp 

info =999
def func(x):
    global info
    print info
    return x**3

pool = mp.Pool()
for i in range(2):
    print "Iteration: ", i
    results = pool.map(func, range(1,10))
    print "Value of info", info
    info += 1
    print results 
    print "Iteration", i, "End"
    print

输出如下:

999
999
999
999
999
999
999
999
999
999
999
999
999
999
999
999
999
999
Iteration:  0
Value of info 999
[1, 8, 27, 64, 125, 216, 343, 512, 729]
Iteration 0 End

Iteration:  1
Value of info 1000
[1, 8, 27, 64, 125, 216, 343, 512, 729]
Iteration 1 End

我想知道为什么在第二次迭代中,再次打印999而不是1000.如何更新全局变量信息以便在第二次迭代中打印1000?非常感谢你!

1 个答案:

答案 0 :(得分:2)

评论已经解释了一下。我想我会解释一下。

使用multiprocessing模块时,它将在pool中按请求的进程数创建新进程。默认值由multiprocessing.cpu_count()计算。

让我们说你编写的脚本是A.py,它创建了进程A。当A创建新进程时,它们被称为A的子进程。这些子进程将具有相同的全局变量,并以A开头。

但是,每个子进程都有单独的范围,因此在一个子进程中更改变量info不会影响其他子进程中info的值。它肯定不会影响父进程A中的值。

一个简单的解决方案是指示每个子进程向父进程info报告A所需的更改。也就是说,map中的每个子进程都应返回-1作为结果,父进程A会在其自己的范围内聚合更新。在分布式计算中,这称为参数服务器设计。

在理想的世界中,你真正想要的是线程,它共享范围和内存。但由于PythonGlobal Interpreter Lock线程可能变得非常复杂。如果您有兴趣,可以对此进行Google搜索。

我误读了你的代码。在我的脑海中凌晨2点,我读到了儿童info的修改和父母的印刷。事实上,情况恰恰相反。

您是正确的,修改点不是跨进程共享的。如果您在子进程中使用global访问info,则子进程将不会知道更改,因为在模块创建时该函数为pickled。您可以在http://grahamstratton.org/straightornamental/entries/multiprocessing

上继续阅读

您需要将动态info作为函数的参数发送给它,如下所示:

import multiprocessing as mp

def dual_input(t):
    info, x = t
    print info
    return x**3

def main():
    info =999
    pool = mp.Pool(2)
    for i in range(2):
        print "Iteration: ", i
        results = pool.map(dual_input, zip([info]*9, range(1,10)))
        print "Value of info", info
        info += 1
        print results
        print "Iteration", i, "End"
        print


if __name__ == '__main__': main()

以上代码打印:

Iteration:  0
999
999
999
999
999
999
999
999
999
Value of info 999
[1, 8, 27, 64, 125, 216, 343, 512, 729]
Iteration 0 End

Iteration:  1
1000
1000
1000
1000
1000
1000
1000
1000
1000
Value of info 1000
[1, 8, 27, 64, 125, 216, 343, 512, 729]
Iteration 1 End