【问题标题】:Writing to dictionary of objects in parallel并行写入对象字典
【发布时间】:2014-05-08 16:29:48
【问题描述】:

我有一个对象字典,我想使用 multiprocessing 包填充这个字典。这段代码并行“运行”多次。

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()

“运行”在哪里进行一些模拟,并将输出保存在 dataobj 对象中

def Run(i, out):
    [...some code to run simulations....]
    out.extract(file)

我的代码创建一个对象字典,然后并行修改该字典中的对象。这可能吗,还是每次修改共享字典中的对象时都需要获取锁?

【问题讨论】:

标签: python dictionary multiprocessing


【解决方案1】:

基本上,当您使用多处理时,您的进程共享原始对象字典的副本,从而填充不同的对象。 multiprocessing 包为您处理的是在进程之间传递 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.

不过,这只是一个设计思路,因为这段代码有一些设计缺陷,在处理真实数据和处理函数时自然会得到解决。

【讨论】:

  • 谢谢!我做了一些不同的事情(而且更笨拙),但对我来说更容易理解。我按照你的建议使用了队列。假设我运行我的进程 n 次。我制作了一个大字典,其中 n 个队列对象作为值,range(1,n) 作为键。每个并行进程使用 queue.put() 写入自己的队列对象,然后我在最后使用 queue.get() 从每个队列中读取并将结果放入我的对象中
  • 是的,唯一重要的是使用一组队列为您的进程提供数据,并使用另一个队列从它们中获取数据。您可以尝试使用一个队列来从所有子进程获取数据到主进程。但绝对要将队列从主进程分离到子进程。
猜你喜欢
  • 2013-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-29
  • 1970-01-01
  • 2018-03-19
  • 2020-10-21
  • 2021-01-19
相关资源
最近更新 更多