Python在多处理进程之间共享一个双端队列

时间:2018-01-16 16:39:20

标签: python python-multiprocessing

我一直在寻找下面的问题,没有任何运气:

Python sharing a dictionary between parallel processes

multiprocessing: sharing a large read-only object between processes?

multiprocessing in python - sharing large object (e.g. pandas dataframe) between multiple processes

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

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)

如何从主代码或运行" print_values"?

的进程中访问mem值?

2 个答案:

答案 0 :(得分:3)

不幸的是multiprocessing.Manager()不支持deque,但它适用于listdictQueueValue和{{1} }}。 Array非常接近,所以我在下面的示例中使用过它。

list

你必须小心使用经理对象。您可以像使用它们引用的对象一样使用它们但是您不能执行类似... 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:]对象移到类外面或在其中移动Manager函数,但是作为一个例子,这是有效的。如果您搬家,请注意,您无法直接在print_values方法中使用self.mem。你需要在启动进程时传入它,或者python在后台执行的run将创建一个新实例并且不会被共享。

希望这适用于您的情况,如果没有,我们可以尝试稍微调整一下。

答案 1 :(得分:3)

因此,通过结合@ 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()