2017-06-18 14 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は全く新しいプロセスを生成してforkし、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

関連する問題