2017-06-18 113 views
1

在下面的代碼中,如何使Starter對象能夠讀取gen.vals? 這似乎是一個不同的對象被創建,其狀態得到更新,但絕不Starter知道這事。此外,該解決方案將如何申請self.vals是一本字典,或任何其他類型的對象?跨進程共享對象狀態?

import multiprocessing 
import time 

class Generator(multiprocessing.Process): 
    def __init__(self): 
     self.vals = [] 
     super(Generator, self).__init__() 

    def run(self): 
     i = 0 
     while True: 
      time.sleep(1) 
      self.vals.append(i) 
      print 'In Generator ', self.vals # prints growing list 
      i += 1 

class Starter(): 
    def do_stuff(self): 
     gen = Generator() 
     gen.start() 
     while True: 
      print 'In Starter ', gen.vals # prints empty list 
      time.sleep(1) 

if __name__ == '__main__': 
    starter = Starter() 
    starter.do_stuff() 

輸出:

In Starter [] 
In Starter [] 
In Generator [0] 
In Starter [] 
In Generator [0, 1] 
In Starter [] 
In Generator [0, 1, 2] 
In Starter [] 
In Generator [0, 1, 2, 3] 
In Starter [] 
In Generator [0, 1, 2, 3, 4] 
In Starter [] 
In Generator [0, 1, 2, 3, 4, 5] 
In Starter [] 
In Generator [0, 1, 2, 3, 4, 5, 6] 
In Starter [] 
In Generator [0, 1, 2, 3, 4, 5, 6, 7] 
+0

https://docs.python.org/2/library/multiprocessing.html。第16.6.1.4節 –

+0

您是否願意演示該示例的解決方案?這是一個最小的,自包含的,可重複的例子,所以它不應該很難。 –

回答

1

當您啓動它在一個完整而獨立的情況下基本上是執行(這裏的一對正在發生的事情在brief explanation),所以沒有共享內存來說話的過程中,因此無論您的run()方法在您的主進程中確實沒有真正反映出來--Python會產生一個全新的進程,在那裏實例化您的Generator並調用它的run()方法,並且在另一個進程停留中調用另一個實例的狀態那裏。

如果你想傳遞數據,你需要使用一些能夠在不同進程之間進行數據序列化/反序列化並且向前和向後傳遞變化的多處理感知結構。例如:

import multiprocessing 
import time 

class Generator(multiprocessing.Process): 
    def __init__(self): 
     self._vals = [] # keeps the internal state 
     self.vals = multiprocessing.Queue() # a queue for the exchange 
     super(Generator, self).__init__() 

    def run(self): 
     i = 0 
     while True: 
      time.sleep(1) 
      self._vals.append(i) # update the internal state 
      print('In Generator ', self._vals) # prints growing list 
      self.vals.put(self._vals) # add it to the queue 
      i += 1 

class Starter(): 
    def do_stuff(self): 
     gen = Generator() 
     gen.start() 
     while True: 
      print('In Starter ', gen.vals.get()) # print what's in the queue 
      time.sleep(1) 

if __name__ == '__main__': 
    starter = Starter() 
    starter.do_stuff() 

會打印出:

In Generator [0] 
In Starter [0] 
In Generator [0, 1] 
In Starter [0, 1] 
In Generator [0, 1, 2] 
In Starter [0, 1, 2] 
In Generator [0, 1, 2, 3] 
In Starter [0, 1, 2, 3] 
etc.

如果你想要做的更復雜/半併發數據修改或處理更多的結構化數據,檢查由multiprocessing.Manager支持的結構。當然,對於非常複雜的東西,我總是建議您使用內存數據庫像Redis進程間數據交換的一種手段。或者,如果你更願意自己做微型管理,ØMQ總是一個不錯的選擇。

+0

這也可以用於字典嗎? –

+0

或者換句話說,爲什麼你的解決方案不適合更多結構化的數據? –

+0

@BaronYugovich - 只要它可以被醃製,它就可以用於任何結構,因爲這是Python的多處理感知結構進行通信的方式。 – zwer