Python多处理池,加入; 不等待继续?

pan*_*via 19 python multiprocessing python-2.7

(1)我试图使用pool.map之后pool.join(),但蟒蛇似乎并没有在等待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()
Run Code Online (Sandbox Code Playgroud)

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

(2)理想情况下,我也想定义foo为局部变量main()并将其传递给f,但是通过制作foo第一个参数f和使用它来做到这一点

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

产生相同的输出.(并且可能还有一个问题,即每个进程现在都有自己的副本foo?)尽管如此,它仍然可以使用普通代码map.

sme*_*eso 26

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

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

我建议你阅读一些文档.

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

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()
Run Code Online (Sandbox Code Playgroud)

你也可以这样做pool.map(functools.partial(f, foo), range(100)),其中foo一个Manager.

  • 调用`pool.close()`和`pool.join()`将确保不仅`map`已终止(如您所指出的那样被阻塞),而且还确保池中的进程已终止并且它们的资源释放。并不是您绝对不需要做的事情,但是如果您不再需要它们了,那就还是很好。 (3认同)
  • 但是,为什么在原始程序中,python在继续通过pool.join()之前不等待pool.map完成? (2认同)
  • 如果使用阻塞的`pool.map()`函数,为什么还需要`pool.join()`?https://docs.python.org/2/library/multiprocessing.html#multiprocessing.pool.multiprocessing.Pool.map (2认同)