2011-10-15 155 views
5

我想在Python 2.6中使用多處理模塊,但顯然有一些我不明白。我希望下面的類加起來()由加載發送給它的編號,並在get_result()方法返回的總和。下面的代碼打印「0」,我想它打印「2」。我錯過了什麼?使用多處理模塊

import multiprocessing 

class AdderProcess(multiprocessing.Process): 

    def __init__(self): 
     multiprocessing.Process.__init__(self) 
     self.sum = 0 
     self.queue = multiprocessing.JoinableQueue(5) 
     self.daemon = True 
     self.start() 

    def run(self): 
     while True: 
      number = self.queue.get() 
      self.sum += number 
      self.queue.task_done() 

    def add(self, number): 
     self.queue.put(number) 

    def get_result(self): 
     self.queue.join() 
     return self.sum 


p = AdderProcess() 
p.add(1) 
p.add(1) 
print p.get_result() 

PS。這個問題已經解決了。感謝您的答案!只是爲了使它更容易爲任何讀者,以下是完整的工作版本:

import multiprocessing 

class AdderProcess(multiprocessing.Process): 

    def __init__(self): 
     multiprocessing.Process.__init__(self) 
     self.sum = multiprocessing.Value('d', 0.0) 
     self.queue = multiprocessing.JoinableQueue(5) 
     self.daemon = True 
     self.start() 

    def run(self): 
     while True: 
      number = self.queue.get() 
      self.sum.value += number 
      self.queue.task_done() 

    def add(self, number): 
     self.queue.put(number) 

    def get_result(self): 
     self.queue.join() 
     return self.sum.value 

p = AdderProcess() 
p.add(1) 
p.add(1) 
print p.get_result() 

回答

6

變化self.sum = 0self.sum = multiprocessing.Value('d', 0.0),並使用self.sum.value訪問或更改值。

class AdderProcess(multiprocessing.Process):  
    def __init__(self): 
     ... 
     self.sum = multiprocessing.Value('d', 0.0) 
     ... 
    def run(self): 
     while True: 
      number = self.queue.get() 
      self.sum.value += number # <-- use self.sum.value 
      self.queue.task_done() 
    def get_result(self): 
     self.queue.join() 
     return self.sum.value   # <-- use self.sum.value 

問題是這樣的:一旦你撥打__init__self.start(),主要工藝叉掉一個子進程。所有值都被複制。現在有兩個版本p。在主進程中,p.sum爲0.在子進程中,run方法被調用,p.sum被增加到2.但是當主進程調用p.get_result()時,其版本仍然具有p.sum等於0. 因此打印0 。

當您想在進程之間共享浮點值時,您需要使用共享機制,例如mp.Value

請參閱「Sharing state between processes」關於如何共享價值觀更多的選擇。

+0

假設你的意思是我應該與你的代碼替換我的初始化,執行時的代碼會導致一個TypeError異常。它對你有用嗎?你能詳細說明你在這裏做什麼嗎? –

+0

對不起,我運行代碼,我只是忘了,包括我的所有更改。您還需要修改'self.sum'爲'self.sum.value'訪問或更改值。 – unutbu

+0

好吧,我想我現在弄明白了。沒有使方法調用進入其他進程的RPC魔術,唯一的共享信息是與爲此目的而提供的數據類型明確共享的信息。我猜是有道理的。謝謝! –

1

self.sum是2 ......在這一過程:

def run(self): 
    while True: 
     number = self.queue.get() 
     print "got %s from queue" % number 
     print "Before adding - self.sum = %d" % self.sum 
     self.sum += number 
     print "After adding - self.sum = %d" % self.sum 
     self.queue.task_done() 

[ 13:56 [email protected] ~ ]$ ./mp.py 
got 1 from queue 
Before adding - self.sum = 0 
After adding - self.sum = 1 
got 1 from queue 
Before adding - self.sum = 1 
After adding - self.sum = 2 

查看如何讓self.sum是在不同的工藝相同multiprocessing 16.3.1.4. - Sharing state between processes

相關問題