繁体   English   中英

python multiprocessing:如何从子进程修改在主进程中创建的字典?

[英]python multiprocessing: How to modify a dictionary created in the main process from a subprocess?

这个问题与: multiprocessing: How do I share a dict 在多个进程之间?

我在多处理字典中存储了多个 numpy 数组。 多处理 dict 在预定义的键处声明并填充有 numpy 数组。 每个子进程仅在 dict 的单个键中写入和修改数据。 即使认为子进程似乎在做某事,字典也不会被子进程更新(不应该在主进程中声明的字典的内存位置“就地”修改字典吗?)。

我不明白为什么它不起作用; dict 中包含的数据是否被复制到每个子进程然后在其中修改而不返回到主进程? 如果是这种情况,有没有办法修改数据而不将其复制到其他地方? 在多处理中,当多个进程尝试写入同一个地址时,可能会出现不需要的数据删除问题,在我的情况下,由于每个子进程只写入一个特定的键,这种不需要的数据删除会成为问题吗?

示例代码:

    
import datetime
import numpy as np
import random
from multiprocessing import Process,Manager

class nbrgen(object):
    def __init__(self,ticker,TBA,delay):
        self.delay=delay
        self.value=100.00
        self.volume=50
        self.ticker=ticker
        self.TBA=TBA

    def generate_value(self):
        self.value=round (self.value + random.gauss(0,1)*self.delay + 0.01 ,2)
        self.volume=random.randint(1,100)

    def __next__(self):
        return self.next()

    def next(self):
        self.generate_value()
        t=datetime.datetime.now(tz=datetime.timezone.utc)
        return np.array([t,self.ticker,self.TBA,self.value,self.volume])

    def apenddict(D, tik,gnr):
      for i in range(8):
        print(tik)
        D[tik][:-1] = D[tik][1:]
        D[tik][-1:, :] = gnr.next()


    if __name__ =="__main__":
     manager=Manager()
     d=manager.dict()
     d["TOK"] = np.zeros((10, 5), dtype="O")
     d["TIK"] = np.zeros((10, 5), dtype="O")
 
     p1=Process(target=apenddict,args=(d,"TIK",nbrgen("TIK","T",0.1)))
     p2=Process(target=apenddict,args=(d,"TOK",nbrgen("TOK","T",0.1)))

     p1.start()
     p2.start()
     p1.join()
     p2.join()

     print(d)

打印:TIK 和 TOK 随机(如预期)和

{'TOK': array([[0, 0, 0, 0, 0],
   [0, 0, 0, 0, 0],
   [0, 0, 0, 0, 0],
   [0, 0, 0, 0, 0],
   [0, 0, 0, 0, 0],
   [0, 0, 0, 0, 0],
   [0, 0, 0, 0, 0],
   [0, 0, 0, 0, 0],
   [0, 0, 0, 0, 0],
   [0, 0, 0, 0, 0]], dtype=object), 'TIK': array([[0, 0, 0, 0, 0],
   [0, 0, 0, 0, 0],
   [0, 0, 0, 0, 0],
   [0, 0, 0, 0, 0],
   [0, 0, 0, 0, 0],
   [0, 0, 0, 0, 0],
   [0, 0, 0, 0, 0],
   [0, 0, 0, 0, 0],
   [0, 0, 0, 0, 0],
   [0, 0, 0, 0, 0]], dtype=object)}

被退回

这是由于Manager()管理dict 仅管理dict本身,而不管理其条目(除非条目恰好是Proxy Objects )。 因此,当使用可变 dict 条目时,管理器不会处理(甚至注册)对象的更新。

但是,可以更新 dict 本身,例如通过替换完整的dict条目。 因此,绕过上述限制的一种方法是获取对条目的本地引用,更新它,然后将本地引用重新分配给托管dict

在这种特殊情况下,这意味着必须稍微修改appenddict函数:

def apenddict(D, tik,gnr):
    tik_array = D[tik]  # Create local reference
    for i in range(8):
        print(tik)
        tik_array[:-1] = D[tik][1:]  # Update local reference
        tik_array[-1:, :] = gnr.next()  # Update local reference
    D[tik] = tik_array  # Assign local reference to managed dict

通过这些更改,您的程序应该可以按您的预期运行更多。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM