【问题标题】:Python multiprocessing pool, join; not waiting to go on?Python多处理池,加入;不等待继续?
【发布时间】:2014-01-21 18:47:11
【问题描述】:

(1) 我正在尝试使用pool.map,后跟pool.join(),但python 似乎并没有等待pool.map 完成,然后继续使用pool.join()。这是我尝试过的一个简单示例:

from multiprocessing import Pool

foo = {1: []}

def f(x):
    foo[1].append(x)
    print foo

def main():
    pool = Pool()
    pool.map(f, range(100))
    pool.close()
    pool.join()
    print foo

if __name__ == '__main__':
    main()

打印输出只是{1: []},好像python 只是忽略了join 命令并在它有机会运行f 之前运行了print foo。预期的结果是foo{1:[0,1,...,99]},并且使用普通的内置python map 给出了这个结果。为什么池化版本打印{1: []},如何更改我的代码以使其打印预期结果?

(2) 理想情况下,我还想将foo 定义为main() 中的局部变量并将其传递给f, 但是通过将foo 设为f 的第一个参数并使用

pool.map(functools.partial(f, foo), range(100))

产生相同的输出。 (并且可能还存在每个进程现在都有自己的foo 副本的问题?)虽然同样,它使用普通的map 来代替。

【问题讨论】:

    标签: python python-2.7 multiprocessing


    【解决方案1】:

    这不是使用map的正确方法。

    1. 以这种方式使用全局变量是绝对错误的。进程不共享相同的内存(通常),因此每个f 都将拥有自己的foo 副本。要在不同进程之间共享变量,您应该使用Manager
    2. 传递给map 的函数通常会返回一个值。

    我建议你阅读一些documentation

    但是这里是一个虚拟示例,说明如何实现它:

    from multiprocessing import Pool
    
    foo = {1: []}
    
    def f(x):
        return x
    
    def main():
        pool = Pool()
        foo[1] = pool.map(f, range(100))
        pool.close()
        pool.join()
        print foo
    
    if __name__ == '__main__':
        main()
    

    您也可以执行pool.map(functools.partial(f, foo), range(100)) 之类的操作,其中fooManager

    【讨论】:

    • 但是,为什么在原始程序中,python 不等待 pool.map 完成就继续通过 pool.join()?
    • Python 等待它,但是父进程的foo 没有改变。池中的每个子进程都会修改自己的 foo 副本,而不是在主进程末尾打印的那个。
    • 如果使用阻塞的pool.map() 函数,为什么还需要pool.join()docs.python.org/2/library/…
    • 调用pool.close()pool.join() 将确保不仅map 已终止(正如您所指出的那样它是阻塞的),而且池中的进程及其资源也已终止释放。不是您绝对需要做的事情,但如果您不再需要它们,无论如何都很好。
    • 这是一个很好的答案,因为您可以使用join,以防您在for_loop 中使用main()
    猜你喜欢
    • 2020-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多