如何在两个进程之间共享数据?
How to share data between two processes?
如何与另一个过程共享一个过程的值?
显然我可以通过多线程而不是多处理来做到这一点。
多线程对我的程序来说很慢。
我无法显示我的确切代码,所以我做了这个简单的例子。
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
的执行是不同的 process/address space 因此 obj
对象 a 必须 serialized/de-serialized 到该进程的地址 space .在那个新地址 space self.var1
遇到初始值 0 然后设置为 5, 但只有 obj
的副本正在修改进程 p1
的地址 space 中的对象;存在于主进程中的该对象的副本尚未被修改。然后,当您启动进程 p2
时,来自主进程的另一个 obj
副本被发送到新进程,但 self.var1
的值仍然为 0。
解决方法是让self.var1
成为multiprocessing.Value
的一个实例,这是一个特殊的变量,存在于共享内存中,所有进程都可以访问。见 docs.
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
备注
针对此特定问题使用共享内存比使用托管 class 更有效,托管 class 由“关闭”注释引用。
5到self.var1.value
的赋值是原子操作,不需要是序列化操作。但是如果:
- 我们正在执行非原子操作(需要多个步骤),例如
self.var1.value += 1
和:
- 多个进程并行执行此非原子操作,然后:
- 我们应该用锁创建值:
self.var1 = Value('i', 0, lock=True)
和:
- 更新锁控制下的值:
with self.var1.get_lock(): self.var1.value += 1
有几种方法可以做到这一点:您可以使用 shared memory, fifo or message passing
如何与另一个过程共享一个过程的值? 显然我可以通过多线程而不是多处理来做到这一点。 多线程对我的程序来说很慢。
我无法显示我的确切代码,所以我做了这个简单的例子。
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
的执行是不同的 process/address space 因此 obj
对象 a 必须 serialized/de-serialized 到该进程的地址 space .在那个新地址 space self.var1
遇到初始值 0 然后设置为 5, 但只有 obj
的副本正在修改进程 p1
的地址 space 中的对象;存在于主进程中的该对象的副本尚未被修改。然后,当您启动进程 p2
时,来自主进程的另一个 obj
副本被发送到新进程,但 self.var1
的值仍然为 0。
解决方法是让self.var1
成为multiprocessing.Value
的一个实例,这是一个特殊的变量,存在于共享内存中,所有进程都可以访问。见 docs.
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
备注
针对此特定问题使用共享内存比使用托管 class 更有效,托管 class 由“关闭”注释引用。
5到self.var1.value
的赋值是原子操作,不需要是序列化操作。但是如果:
- 我们正在执行非原子操作(需要多个步骤),例如
self.var1.value += 1
和: - 多个进程并行执行此非原子操作,然后:
- 我们应该用锁创建值:
self.var1 = Value('i', 0, lock=True)
和: - 更新锁控制下的值:
with self.var1.get_lock(): self.var1.value += 1
有几种方法可以做到这一点:您可以使用 shared memory, fifo or message passing