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

标签 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?非常感谢!

最佳答案

评论已经解释了一些。我想我会解释更多一点。

当使用多处理模块时,它将根据中请求的进程数量创建新进程。默认值由 multiprocessing.cpu_count() 计算。

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

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

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

在理想的世界中,您真正想要的是共享作用域和内存的线程。但由于全局解释器锁Python 线程可能会变得非常复杂。如果您有兴趣,可以对此进行一些 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

关于python - 在循环中使用 multiprocessing.pool 并更新目标函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47402616/

相关文章:

python - 从列表列表中检索并返回字母的函数

python - 如何在单台机器上使用多处理运行 Locust

python - 缓冲区错误 : could not get scalar buffer information

python - 当放置在 models.py 外部时,Django 信号不起作用

python - 使用内联图像和 PDF 附件创建 HTML 邮件

Python - 逐字节读取UTF-8编码的字符串

jquery - 使用 jquery 调用 ajax 后如何等待图像加载?

python - 使用 Dataframe 进行多处理和队列

python - 在 python 中实现此工作流的最佳方式

python - 多处理和模块