跨进程共享对象状态?

2024-04-25 16:54:27 发布

您现在位置:Python中文网/ 问答频道 /正文

{{cd2>如何在cd2>中读取? 似乎创建了一个不同的对象,其状态得到更新,但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()

输出:

^{pr2}$

Tags: 对象importselftruetimeinitdefgenerator
1条回答
网友
1楼 · 发布于 2024-04-25 16:54:27

当您启动一个进程时,它实际上是在一个完全独立的上下文中执行的(这里有一个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()

将打印:

^{pr2}$

如果要进行更复杂/半并发的数据修改或处理更结构化的数据,请检查^{}支持的结构。当然,对于非常复杂的东西,我总是建议使用内存中的数据库,比如Redis作为进程间数据交换的手段。或者,如果你喜欢自己做微观管理,ØMQ总是一个不错的选择。在

相关问题 更多 >