Python在多个处理进程之间共享数据

Python在多个处理进程之间共享数据,python,python-multiprocessing,Python,Python Multiprocessing,在考绩制度的一小时里,我一直在看以下问题,但运气不好: 我已经编写了一个非常基本的测试文件来说明我要做的事情: from collections import deque from multiprocessing import Process import numpy as np class TestClass: def __init__(self): self.mem = deque(maxlen=4) self.process = Proce

在考绩制度的一小时里,我一直在看以下问题,但运气不好:

我已经编写了一个非常基本的测试文件来说明我要做的事情:

from collections import deque
from multiprocessing import Process
import numpy as np


class TestClass:
    def __init__(self):
        self.mem = deque(maxlen=4)
        self.process = Process(target=self.run)

    def run(self):
        while True:
            self.mem.append(np.array([0, 1, 2, 3, 4]))


def print_values(x):
    while True:
        print(x)


test = TestClass()
process = Process(target=print_values(test.mem))

test.process.start()
process.start()
目前,这将产生以下结果:

deque([], maxlen=4)

如何从主代码或运行“打印值”的进程访问mem值?

不幸的是,
多处理。Manager()
不支持
deque
,但它可以与
列表
dict
队列
数组
一起使用。
列表
非常接近,因此我在下面的示例中使用了它

from multiprocessing import Process, Manager, Lock
import numpy as np

class TestClass:
    def __init__(self):
        self.maxlen = 4
        self.manager = Manager()
        self.mem = self.manager.list()
        self.lock = self.manager.Lock()
        self.process = Process(target=self.run, args=(self.mem, self.lock))

    def run(self, mem, lock):
        while True:
            array = np.random.randint(0, high=10, size=5)
            with lock:
                if len(mem) >= self.maxlen:
                    mem.pop(0)
                mem.append(array)

def print_values(mem, lock):
    while True:
        with lock:
            print mem

test = TestClass()
print_process = Process(target=print_values, args=(test.mem, test.lock))
test.process.start()
print_process.start()

test.process.join()
print_process.join()
使用管理器对象时必须稍微小心。你可以像他们引用的对象一样使用它们,但你不能像
mem=mem[-4:]
截断值,因为您正在更改引用的对象

至于编码风格,我可以将
管理器
对象移到类外,或者将
打印值
函数移到类内,但举个例子,这是可行的。如果您移动东西,只需注意不能在
run
方法中直接使用
self.mem
。您需要在启动流程时传入它,否则python在后台执行的
fork
将创建一个新实例,并且不会被共享


希望这适用于您的情况,如果不适用,我们可以尝试对其进行一些调整。

因此,通过结合@bivouac0提供的代码和@Marijn Pieters发布的注释,我提出了以下解决方案:

from multiprocessing import Process, Manager, Queue


class testClass:
    def __init__(self, maxlen=4):
        self.mem = Queue(maxsize=maxlen)
        self.process = Process(target=self.run)

    def run(self):
        i = 0

        while True:
            self.mem.empty()
            while not self.mem.full():
                self.mem.put(i)
                i += 1


def print_values(queue):
    while True:
        values = queue.get()
        print(values)


if __name__ == "__main__":
    test = testClass()
    print_process = Process(target=print_values, args=(test.mem,))

    test.process.start()
    print_process.start()

    test.process.join()
    print_process.join()

你需要仔细阅读或。您的子进程每获得一个deque的分叉副本,它们之间没有进一步的连接。你可能想要一个。谢谢你花时间回答这个问题。我已经实现了您的代码,但我遇到了以下错误:_pickle.PicklingError:无法pickle:内置项上的属性查找weakref失败我尝试使用以下代码将进程移到类外,但没有任何运气:test.process=process(target=test.run,args=(test.mem,test.lock))我已经用您提供的部分代码和@Marijn Pieters给我的提示解决了这个问题。我将在下面发布我的解决方案:)