Python多处理.Process:从局部变量开始

2022-04-10 00:00:00 python python-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


解决方案

摘自:Beazley的基本参考:

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

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

因此,他们不应该做同样的事情。在我看来,在本例中,p.run()是为正在进行的进程调用的,p.start()在一个新进程中调用p.run(),该新进程带有传递给构造函数的原始目标(其中l仍然是[])。

相关文章