变量在 Python 多处理中没有改变
Variable does not change in Python multiprocessing
我正在尝试在我的多处理代码中使用字典。
问题是当我在过程中更改一个键的值时,更改只会影响该过程。
显然,流程的可变参数是该变量的副本。我尝试使用 dict 方法,但它也不起作用。
我的错误是什么?
import time
from multiprocessing import Process, Manager
def f1(list1, set1):
list1.append(3)
set1['func']='f1'
print('f1 dic',set1)
print('f1 list',list1)
while True:
time.sleep(3)
print('f1 dic',set1)
print('f1 list',list1)
def f2(list1):
list1.append(4)
settings_dic['func']='f2'
print('f2 dic',settings_dic)
print('f2 list',list1)
while True:
time.sleep(3)
print('f2 dic',settings_dic)
print('f2 list',list1)
if __name__ == '__main__':
# list1 = Manager().dict()
settings_dic = Manager().dict()
Global = Manager().Namespace()
list1 = [1,2]
settings_dic = {
'mode' : 'master',
'logger' : 'True',
'func' : ''
}
p_video_get = Process(target=f1, args=(list1,settings_dic,))
p_video_get.daemon = True
p_video_get.start()
p_packetTrasnmission = Process(target=f2, args=(list1,))
p_packetTrasnmission.daemon = True
p_packetTrasnmission.start()
list1.append(5)
settings_dic['func'] = 'main'
print('main dic',settings_dic)
print('main list',list1)
while True:
time.sleep(3)
print('main dic',settings_dic)
print('main list',list1)
更新:
正如 juanpa.arrivillaga 所指出的,上面代码的问题是 Manager.dict()
被重新分配为正常的 dict
,这意味着它丢失了对 Manager.dict()
而不是 changing/passing 那个。其余的是我原来的回复,我认为 OP 只是想传递一本字典。
原创:
当您启动一个单独的进程时,该进程有自己的地址 space。除非您进行设置,否则它们不会共享任何内存(以及数据)。每个进程都会获得您传入的参数的副本,并且它们进程的内存管理自己的副本(这是通过 pickle 对象并将其发送到新进程来完成的)。一旦复制,它们就不会同步。要让一个进程更改另一个进程中的数据,您有两种选择。
您要么需要通过 shared comms or shared object 设置一些 IPC。队列是 post 更新数据结构的一种简单方法,其他进程可以弹出并更新自己的副本。
或者,如果您使用的是 3.8+,则可以设置 shared memory。我没有这样做,您仍然需要编写代码来监视和解码更改。但这是让一个进程与另一个进程通信的另一种方式。
我正在尝试在我的多处理代码中使用字典。 问题是当我在过程中更改一个键的值时,更改只会影响该过程。 显然,流程的可变参数是该变量的副本。我尝试使用 dict 方法,但它也不起作用。 我的错误是什么?
import time
from multiprocessing import Process, Manager
def f1(list1, set1):
list1.append(3)
set1['func']='f1'
print('f1 dic',set1)
print('f1 list',list1)
while True:
time.sleep(3)
print('f1 dic',set1)
print('f1 list',list1)
def f2(list1):
list1.append(4)
settings_dic['func']='f2'
print('f2 dic',settings_dic)
print('f2 list',list1)
while True:
time.sleep(3)
print('f2 dic',settings_dic)
print('f2 list',list1)
if __name__ == '__main__':
# list1 = Manager().dict()
settings_dic = Manager().dict()
Global = Manager().Namespace()
list1 = [1,2]
settings_dic = {
'mode' : 'master',
'logger' : 'True',
'func' : ''
}
p_video_get = Process(target=f1, args=(list1,settings_dic,))
p_video_get.daemon = True
p_video_get.start()
p_packetTrasnmission = Process(target=f2, args=(list1,))
p_packetTrasnmission.daemon = True
p_packetTrasnmission.start()
list1.append(5)
settings_dic['func'] = 'main'
print('main dic',settings_dic)
print('main list',list1)
while True:
time.sleep(3)
print('main dic',settings_dic)
print('main list',list1)
更新:
正如 juanpa.arrivillaga 所指出的,上面代码的问题是 Manager.dict()
被重新分配为正常的 dict
,这意味着它丢失了对 Manager.dict()
而不是 changing/passing 那个。其余的是我原来的回复,我认为 OP 只是想传递一本字典。
原创:
当您启动一个单独的进程时,该进程有自己的地址 space。除非您进行设置,否则它们不会共享任何内存(以及数据)。每个进程都会获得您传入的参数的副本,并且它们进程的内存管理自己的副本(这是通过 pickle 对象并将其发送到新进程来完成的)。一旦复制,它们就不会同步。要让一个进程更改另一个进程中的数据,您有两种选择。
您要么需要通过 shared comms or shared object 设置一些 IPC。队列是 post 更新数据结构的一种简单方法,其他进程可以弹出并更新自己的副本。
或者,如果您使用的是 3.8+,则可以设置 shared memory。我没有这样做,您仍然需要编写代码来监视和解码更改。但这是让一个进程与另一个进程通信的另一种方式。