更新我的多个进程后,实例变量不变

时间:2014-10-25 09:54:58

标签: python python-2.7 multiprocessing

对于以下代码,我希望dr.hello的输出为 10 ,因为10个生成的进程会调用updateHello一次以递增dr.hello。但它现在 0 ,原因是什么,如何更改呢?

from multiprocessing import Process, Lock

class myWorker:
    def __init__(self, lock, driver, i):
        self.idx=i
        self.driver=driver
        self.lock=lock

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

class driver:
    hello=0
    def __init__(self):
        self.lock=Lock()

    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 updateHello(self,l,i):
        l.acquire()
        self.hello+=1
        print "update from",i
        l.release()

if __name__=='__main__':
    dr=driver()
    dr.run()
    print dr.hello

2 个答案:

答案 0 :(得分:0)

我认为共享变量需要multiprocessing.Value

from multiprocessing import Process, Lock, Value

class myWorker:
    def __init__(self, lock, driver, i):
        self.idx=i
        self.driver=driver
        self.lock=lock

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

class driver:
    hello = Value("i",lock=True) # create shared variable of type int
    hello.value = 0

    def __init__(self):
        self.lock=Lock()

    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 updateHello(self,l,i):
        with self.lock: # acquire lock
            driver.hello.value += 1
            print ("update from", i)
        # release lock

if __name__=='__main__':
    dr=driver()
    dr.run()
    print(driver.hello.value)

Ipython输出:

if __name__=='__main__':
    dr=driver()
    dr.run()
    print(driver.hello.value)

## -- End pasted text --
('update from', 0)
('update from', 1)
('update from', 2)
('update from', 5)
('update from', 6)
('update from', 7)
('update from', 4)
('update from', 3)
('update from', 8)
('update from', 9)
10

答案 1 :(得分:0)

现在,我可以通过将Padraic解决方案从类变量更改为实例变量

来实现
from multiprocessing import Process, Lock, Value

class myWorker:
    def __init__(self, lock, driver, i):
        self.idx=i
        self.driver=driver
        self.lock=lock

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

class driver(object):
    #hello = Value("i",lock=True) # create shared variable of type int
    #hello.value = 0

    def __init__(self):
        self.lock=Lock()
        self.hello=Value("i",0)

    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 updateHello(self,l,i):
        with self.lock: # acquire lock
            self.hello.value += 1
            print ("update from", i)
        # release lock

if __name__=='__main__':
    dr=driver()
    dr.run()
    print(dr.hello.value)