计算由multiprocessing.Queue处理多少元素由子类multiprocessing.Queue

时间:2017-10-24 05:45:42

标签: python multiprocessing

我想知道有多少元素被用于多处理.Queue。我的实现是通过继承multiprocessing.Queue:

import multiprocessing
from multiprocessing.queues import Queue


class QueueFPS(Queue):
    def __init__(self, maxsize=200):
        self.frame_count = 0
        ctx = multiprocessing.get_context()
        super().__init__(maxsize, ctx=ctx)

    def put(self,*args, **kwargs):
        self.frame_count += 1
        print("count in put function: ", self.frame_count)
        super().put(*args, **kwargs)

    def get_count(self):
        print("count in get_count: ", self.frame_count)

但是当我使用这个类时,我发现如果我用多个进程运行它,get_count()方法总是返回0:

def worker(test_queue):
    for i in range(2):
        test_queue.put("A")

def test_multi_process():
    test_queue = QueueFPS()
    test_process = multiprocessing.Process(
                    target=worker,
                    args=(test_queue,))
    test_process.start()
    test_process.join()
    test_queue.close()
    test_queue.join_thread()
    print(test_queue.get_count())

输出是:

count in put function:  1
count in put function:  2
count in get_count:  0

如果我只使用一个进程运行它,它按预期工作,但它会引发异常(我省略了一些异常输出)

def test_single_process():
    test_queue = QueueFPS()
    for i in range(2):
        test_queue.put("A")
    print(test_queue.get_count())

输出是:

count in put function:  1
count in put function:  2
count in get_count:  2
None
>>> Traceback (most recent call last):
   (I omit some output here)
BrokenPipeError: [Errno 32] Broken pipe

2 个答案:

答案 0 :(得分:0)

您在子进程中调用put方法。因此,您的put仅更改该进程中的Queue对象。这些更改不会自动传播到其他进程you need to take special measures。 (Queue本身使用Pipe和自定义逻辑在进程之间传递pickled项,而且这是唯一连接其副本的东西。)

答案 1 :(得分:0)

frame_count 不会在进程间共享,因此在使用多个进程时您无法获得所需的输出。如果您尝试打印

  

self.qsize()

这实际上是Queue类对象的一个​​属性,你会看到它打印2。

这样做的原因是如何实现Queue是线程安全的和过程安全的。以下是Python文档所说的内容:

  

class multiprocessing.Queue([maxsize])

     

返回进程共享队列   使用管道和一些锁/信号量实现。当一个过程   首先将一个项目放在队列上,启动一个馈线线程   将对象从缓冲区传输到管道中。

由于 frame_count 属性的状态未在进程间同步,因此无法获得所需的输出。