Search code examples
pythonpython-2.7multiprocessing

Value update in manager.dict not reflected


I expect the following code to print [{0: 100}], since it do the plus in updateList for a hundred time In turn, it prints [{0: 0}] what's the problem and how to rectify 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)

Solution

  •  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 the docs

    Note Modifications to mutable values or items in dict and list proxies will not be propagated through the manager, because the proxy has no way of knowing when its values or items are modified. To modify such an item, you can re-assign the modified object to the container proxy:

    Seeing as you already have dict1, you can update directly:

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