Python multiprocessing.Process:从局部变量开始

时间:2015-09-21 19:26:49

标签: python python-multiprocessing

我试图了解multiprocessing.Process类。我想收集数据异步存储在某个地方。存储数据后,它会以某种方式丢失。这是我的MWE:

from __future__ import print_function
import multiprocessing as mp

def append_test(tgt):
    tgt.append(42)
    print('Appended:', tgt)

l = []
p = mp.Process(target=lambda: append_test(l))

p.run()
print('l is', l)

p.start()
p.join()
print('l is', l)

如果我正在运行该片段,我会

Appended: [42]
l is [42]
Appended: [42, 42]
l is [42]

如您所见,调用run和使用start / join之间存在差异。它与订单无关(使用后续运行) - 我试过了。有人可以详细说明第二个42如何丢失?它似乎存放在某个时间?但在其他时候它绝对不是。

以防万一可能会有所不同:我尝试过python2.7和python3.4,两者都具有完全相同的结果。

更新:显然只有start才会生成一个新进程,之后将调用run。然后我的实际问题转换为以下问题:如何将l传递给生成的进程s.t.我能看到实际结果吗?

解决方案:以下示例说明如何安全地将共享数据传递给流程:

from __future__ import print_function
import multiprocessing as mp

def append_test(tgt):
    tgt.append(42)
    print('Appended:', tgt)

m = mp.Manager()
l = m.list()
p = mp.Process(target=lambda: append_test(l))

p.start()
p.join()
print('l is', l)

进一步阅读:Multiprocessing Managers Documentation

2 个答案:

答案 0 :(得分:0)

Run执行您在多处理中定位的可调用对象。 Start将调用该对象的run()方法。

来自multiprocessing's documentation

  
    

run()表示进程活动的方法。

  
     

您可以在子类中覆盖此方法。标准的run()方法   调用传递给对象构造函数的可调用对象作为   目标参数,如果有的话,采用顺序和关键字参数   分别来自args和kwargs论证。

     

start()开始进程的活动。

     

每个进程对象最多只能调用一次。它安排   对象的run()方法将在一个单独的进程中调用。

答案 1 :(得分:0)

来自Python:Beazley的基本参考:

p.run():进程启动时运行的方法。默认情况下,这会调用传递给Process构造函数的目标。 ...

p.start():启动该过程。这将启动表示进程的子进程,并在该子进程中调用p.run()。

所以,他们并不打算做同样的事情。在我看来,就像在这种情况下,正在为正在进行的进程调用p.run(),并且p.start()在一个新进程中调用p.run(),并将原始目标传递给构造函数(其中)我还是[]