如何在运行脚本时将更多项目添加到多处理队列中

时间:2019-06-20 13:30:29

标签: python python-3.x multiprocessing python-multiprocessing

我正在尝试通过队列学习多处理。

我想做的是找出脚本运行时何时/如何“将更多项目添加到队列”。

以下脚本是我正在使用的基准:

import multiprocessing


class MyFancyClass:

    def __init__(self, name):
        self.name = name

    def do_something(self):
        proc_name = multiprocessing.current_process().name
        print('Doing something fancy in {} for {}!'.format(
            proc_name, self.name))


def worker(q):
    obj = q.get()
    obj.do_something()


if __name__ == '__main__':
    queue = multiprocessing.Queue()

    p = multiprocessing.Process(target=worker, args=(queue,))
    p.start()

    queue.put(MyFancyClass('Fancy Dan'))
    queue.put(MyFancyClass('Frankie'))
    print(queue.qsize())

    # Wait for the worker to finish
    queue.close()
    queue.join_thread()
    p.join()

在第26行,Fancy Dan注入有效,但Frankie无效。我能够确认Frankie确实进入了队列。我需要一个可以“检查更多项目”并将其根据需要插入队列的位置。如果不存在更多项目,请在清除现有项目后关闭队列。

我该怎么做?

谢谢!

2 个答案:

答案 0 :(得分:2)

让我们说清楚:

  • 目标函数worker(q)在上述方案中仅被调用一次。在第一次调用时,该函数将暂停等待阻塞操作q.get()的结果。它从MyFancyClass('Fancy Dan')获取实例queue,调用其do_something方法并完成操作。
  • MyFancyClass('Frankie')将被放入队列,但由于完成了流程的目标功能,因此不会进入流程。
  • 其中一种方法是从队列中读取并等待信号/标记项,该信号/标记项表明队列使用已停止。假设None的值。

import multiprocessing


class MyFancyClass:

    def __init__(self, name):
        self.name = name

    def do_something(self):
        proc_name = multiprocessing.current_process().name
        print('Doing something fancy in {} for {}!'.format(proc_name, self.name))


def worker(q):
    while True:
        obj = q.get()
        if obj is None:
            break
        obj.do_something()


if __name__ == '__main__':
    queue = multiprocessing.Queue()

    p = multiprocessing.Process(target=worker, args=(queue,))
    p.start()

    queue.put(MyFancyClass('Fancy Dan'))
    queue.put(MyFancyClass('Frankie'))
    # print(queue.qsize())
    queue.put(None)

    # Wait for the worker to finish
    queue.close()
    queue.join_thread()
    p.join()

输出:

Doing something fancy in Process-1 for Fancy Dan!
Doing something fancy in Process-1 for Frankie!

答案 1 :(得分:0)

您可以通过将worker更改为

def worker(q):
    while not q.empty():
        obj = q.get()
        obj.do_something()

您的原始代码存在的问题是,工作人员在对队列中的一项进行处理后返回。您需要某种循环逻辑。

此解决方案是不完善的,因为empty()不是reliable。如果在添加更多项目之前队列变空,也会失败(该过程将返回)。

我建议使用Process Pool Executor

Submit非常接近您要寻找的内容。