Updating value in manager.dict is not reflected

I expect the following code to print [{0: 100}], since it makes a plus updateLista hundred times. In turn, it prints [{0: 0}] what problem and how to fix it?

from multiprocessing import Process, Lock, Value,Manager
class myWorker:
    def __init__(self, lock, driver, i):
        self.idx=i
        self.driver=driver
        self.lock=lock

    def run(self):
        self.driver.updateList(self.lock,self.idx)

class driver(object):

    def __init__(self):
        manager=Manager()
        self.lock=Lock()
        self.lst=manager.list()
        self.dict1=manager.dict({0:0})
        self.lst.append(self.dict1)

    def workerrun(self,lock, i):
        worker1=myWorker(lock,self,i)
        worker1.run()

    def run(self):
        D=[Process(target=self.workerrun,args=(self.lock,i)) for i in range(10)]
        for d in D:
            d.start()
        for d in D:
            d.join()

    def updateList(self,l,i):
        with self.lock: # acquire lock
            for j in range(10):
                self.lst[0][0]+=1

            print ("update from", i)

if __name__=='__main__':
    dr=driver()
    dr.run()
    print(dr.lst)
+4
source share
3 answers
 def updateList(self,l,i):
        with self.lock: # acquire lock
            for j in range(10):
                d = self.lst[0]
                d[0] += 1
                self.lst[0]=d
                print ("update from", i,self.lst[0])

from docs

Note. Changes to mutable values ​​or elements in the dict and list proxy files will not be transmitted through the dispatcher, since the proxy server does not know when its values ​​or elements will be changed. To change such an element, you can reassign the changed object to the container proxy:

, dict1, :

   def updateList(self,l,i):
        with self.lock: # acquire lock
            for j in range(10):
                self.dict1[0]+=1
                print ("update from", i,self.lst[0])
+5

, .

def updateList(self,l,i):
    with self.lock: # acquire lock
        for j in range(10):
            self.dict1[0] += 1
        print ("update from", i)

, 10? self.dict1[0] += 10.

0

multiprocessing.Manager()returns multiprocessing.managers.SyncManager, if you see, when you created the list and the dictionary, you actually received your proxies. This means that you did not add to the list {0:0}that you created inside the manager, but a proxy (copy).

self.dict1=manager.dict({0:0})
#this:
self.lst.append(self.dict1)
#is the same as doing this:
self.lst.append({0:0})   

So, in the updatelist method:

def updateList(self,l,i):
    with self.lock: # acquire lock
        for j in range(10):
            self.lst[0][0]+=1

            # is the same as doing:
            # example: self.lst == [{0:x}]
            proxy = self.lst
            # you get a copy of actual list
            # proxy == [{0:x}]
            dict = proxy[0]
            dict[0]+=1
            # proxy == [{0:x+1}]
            # BUT
            # self.lst == [{0:x}]

This means that you make copies, change them, and then do not use. You need to change to assign a list with a new value so that it changes for all processes:

def updateList(self,l,i):
    with self.lock: # acquire lock
        dict0 = self.lst[0]
        for j in range(10):
            dict0[0]+=1
        self.lst[0] = dict0
0
source

All Articles