簡體   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