跨进程共享对象状态?

时间:2017-06-18 02:39:16

标签: python multiprocessing python-multiprocessing

在下面的代码中,如何让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]

1 个答案:

答案 0 :(得分:1)

当你开始一个过程时,它基本上是在一个完整的单独环境中执行的(这里是关于正在进行的事情的brief explanation)所以没有共享内存可言,所以无论你的{ {1}}方法确实没有在您的主进程中反映出来 - Python从中生成/分叉一个全新的进程,在那里实例化run()并调用其Generator方法和任何更改在另一个过程中的另一个实例的状态停留在那里。

如果要传递数据,则需要使用一些多处理感知结构,这些结构将在不同进程之间实质上序列化/反序列化数据,并反复传递更改。例如:

run()

将打印出来:

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始终是一个不错的选择。