如何在两个进程之间共享数据?



如何与一个进程共享另一个进程的值? 显然,我可以通过多线程而不是多处理来做到这一点。 多线程对我的程序来说很慢。

我无法显示我的确切代码,所以我做了这个简单的例子。

from multiprocessing import Process
from threading import Thread
import time
class exp:
def __init__(self):
self.var1 = 0

def func1(self):
self.var1 = 5
print(self.var1)
def func2(self):
print(self.var1) 

if __name__ == "__main__":
#multithreading
obj1 = exp()
t1 = Thread(target = obj1.func1)
t2 = Thread(target = obj1.func2)
print("multithreading")
t1.start()
time.sleep(1)
t2.start()
time.sleep(3)

#multiprocessing
obj = exp()
p1 = Process(target = obj.func1)
p2 = Process(target = obj.func2)
print("multiprocessing")
p1.start()
time.sleep(2)
p2.start()

预期产出

multithreading
5
5
multiprocessing
5
5

实际输出

multithreading
5
5
multiprocessing
5
0

我知道有几个人投票反对这个问题,但所谓的重复问题的答案并没有真正解释为什么OP 的程序不能按原样工作,并且提供的解决方案不是我建议的。因此:

让我们分析一下正在发生的事情。obj = exp()的创建由主进程完成。exp.func1的执行是不同的进程/地址空间,因此obj对象 a 必须序列化/反序列化为该进程的地址空间。在新的地址空间中,self.var1遇到初始值 0,然后设置为 5,但只修改进程p1的地址空间中的obj对象的副本;主进程中存在的该对象的副本尚未被修改。然后,当您启动进程p2时,主进程中的另一个obj副本将发送到新进程,但仍self.var1值为 0。

解决方案是让self.var1成为multiprocessing.Value的实例,这是一个存在于所有进程都可以访问的共享内存中的特殊变量。请参阅文档。

from multiprocessing import Process, Value
class exp:
def __init__(self):
self.var1 = Value('i', 0, lock=False)
def func1(self):
self.var1.value = 5
print(self.var1.value)
def func2(self):
print(self.var1.value)

if __name__ == "__main__":
#multiprocessing
obj = exp()
p1 = Process(target = obj.func1)
p2 = Process(target = obj.func2)
print("multiprocessing")
p1.start()
# No need to sleep, just wait for p1 to complete
# before starting p2:
#time.sleep(2)
p1.join()
p2.start()
p2.join()

指纹:

multiprocessing
5
5

注意

对这个特定问题使用共享内存比使用托管类要有效得多,托管类由"close"注释引用。

将 5 分配给self.var1.value原子操作,不需要是序列化操作。但是,如果:

  1. 我们正在执行非原子操作(需要多个步骤),例如self.var1.value += 1和:
  2. 多个进程并行执行此非原子操作,然后:
  3. 我们应该用锁创建值:self.var1 = Value('i', 0, lock=True)和:
  4. 更新锁控制下的值:with self.var1.get_lock(): self.var1.value += 1

有几种方法可以做到这一点: 您可以使用共享内存、FIFO 或消息传递

相关内容

  • 没有找到相关文章

最新更新