并行写入对象字典
我有一个包含多个对象的字典,我想用多进程的方式来填充这个字典。这个代码片段会同时多次运行“Run”。
Data=dict()
for i in range:
Data[i]=dataobj(i) #dataobj is a class I have defined elsewhere
proc=Process(target=Run, args=(i, Data[i]))
proc.start()
其中“Run”会进行一些模拟,并把结果保存到dataobj对象里。
def Run(i, out):
[...some code to run simulations....]
out.extract(file)
我的代码创建了一个对象字典,然后在这个字典中并行修改这些对象。这种做法可行吗?还是说每次修改共享字典中的对象时,我都需要获取一个锁?
1 个回答
4
简单来说,当你使用多进程时,你的每个进程都会共享原始字典对象的“副本”,所以它们会填充不同的内容。多进程包为你处理的是在进程之间传递Python对象的消息,这样可以让事情变得简单一些。
一个好的设计思路是让主进程负责填充字典,而让它的子进程来处理具体的工作。然后使用队列在子进程和主进程之间交换数据。
作为一个一般的设计思路,这里有一些可以做的事情:
from queue import Queue
queues = [Queue(), Queue()]
def simulate(qin, qout):
while not qin.empty():
data = qin.pop()
# work with the data
qout.put(data)
# when the queue is empty, the process ends
Process(target=simulate, args=(queues[0][0],queues[0][1])).start()
Process(target=simulate, args=(queues[1][0],queues[1][1])).start()
processed_data_list = []
# first send the data to be processed to the children processes
while data.there_is_more_to_process():
# here you have to adapt to your context how you want to split the load between your processes
queues[0].push(data.pop_some_data())
queues[1].push(data.pop_some_data())
# then for each process' queue
for qin, qout in queues:
# you populate your output data list (or dict or whatever)
while not qout.empty:
processed_data_list.append(qout.pop())
# here again, you have to adapt to your context how you handle the data sent
# back from the children processes.
不过,这只是一个设计思路,因为这段代码有一些设计缺陷,这些缺陷在处理真实数据和处理函数时会自然得到解决。