2017-06-18 149 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