当前位置: 首页 > 面试题库 >

如何使用multiprocessing.Queue.get方法?

施招
2023-03-14
问题内容

下面的代码将三个数字放在一个队列中。然后,它尝试从队列中取回数字。但是它从来没有。如何从队列中获取数据?

import multiprocessing

queue = multiprocessing.Queue()

for i in range(3):
    queue.put(i)

while not queue.empty():
    print queue.get()

问题答案:

在阅读@Martijn
Pieters的文章后,我最初删除了此答案,因为他更详细地描述了“为什么这不起作用”以及更早的版本。然后我意识到,OP的示例中的用例并不完全符合

“如何使用multiprocessing.Queue.get方法”。

这不是因为没有用于演示的子进程,而是因为在实际的应用程序中,几乎没有预先填充队列,而是仅在队列之后才读出,而是在等待时间之间交错读写。Martijn演示的扩展演示代码在通常情况下不起作用,因为当入队不符合阅读要求时,while循环可能会中断得太早。因此,这里是重新加载的答案,它能够处理通常的交错提要和阅读方案:

不要依赖queue.empty检查同步。

将对象放在空队列上之后,在队列的empty()方法返回False且get_nowait()可以在不引发queue.Empty的情况下返回之前,可能会有无穷的延迟。…

空()

如果队列为空,则返回True,否则返回False。由于多线程/多处理语义,这是不可靠的。docs

从队列中使用for msg in iter(queue.get, sentinel):to .get(),您都可以通过传递哨兵值来中断循环…
iter(callable,sentinel)?

from multiprocessing import Queue

SENTINEL = None

if __name__ == '__main__':

    queue = Queue()

    for i in [*range(3), SENTINEL]:
        queue.put(i)

    for msg in iter(queue.get, SENTINEL):
        print(msg)

…或在需要非阻塞解决方案时使用get_nowait()并处理可能的queue.Empty异常。

from multiprocessing import Queue
from queue import Empty
import time

SENTINEL = None

if __name__ == '__main__':

    queue = Queue()

    for i in [*range(3), SENTINEL]:
        queue.put(i)

    while True:
        try:
            msg = queue.get_nowait()
            if msg == SENTINEL:
                break
            print(msg)
        except Empty:
            # do other stuff
            time.sleep(0.1)

如果只有一个进程并且该进程中只有一个线程正在读取队列,则还可以与以下交换最后一个代码片段:

while True:
    if not queue.empty():  # this is not an atomic operation ...
        msg = queue.get()  # ... thread could be interrupted in between
        if msg == SENTINEL:
            break
        print(msg)
    else:
        # do other stuff
        time.sleep(0.1)

由于线程可能会在检查和之间删除GIL,因此这不适用于进程中的多线程队列读取。如果从队列中读取多个进程,则同样适用。if not queue.empty()``queue.get()

对于单一生产者/单一消费者的方案,使用amultiprocessing.Pipe代替multiprocessing.Queue将是足够的,并且性能更高。



 类似资料:
  • 尝试在 Flutter 中为 Firebase 电子邮件/密码身份验证方法设置firebase_auth包,但需要电子邮件验证方面的帮助。 我是通过sendEmailVerification()来的;方法由firebase_auth软件包提供,但需要一些有关设置的建议。有没有人有一个工作代码示例可以遵循? 如果可能的话,任何帮助、建议、指导都将不胜感激。

  • 嘿,我是python新手,正在使用tkinter作为我的gui。我在使用“after”方法时遇到问题。目标是每5秒出现一个随机字母。 这是我的代码: 谁能帮帮我吗?问题肯定出在框架上。(500)之后:我不确定使用“frame”是否正确,我不知道500后面的参数是什么。 谢啦

  • 问题内容: 正在将tkinter用于gui,我在使用之后方法时遇到麻烦。目的是使每5秒出现一个随机字母。 这是我的代码: 有人可以帮我吗—问题肯定是frame.after(500):我不确定使用“ frame”是否正确,我也不知道500后面是哪个参数。 问题答案: 您需要给定一个在时间延迟后要调用的函数,作为第二个参数after: 注册在给定时间后调用的警报回调。 因此,您真正想要做的是: 您还需

  • 本文向大家介绍如何使用Java子串方法?,包括了如何使用Java子串方法?的使用技巧和注意事项,需要的朋友参考一下 String类的方法具有两个变体,并返回一个新字符串,该字符串是当前字符串的子字符串。子字符串以指定索引处的字符开头,并延伸到该字符串的末尾,或者直到给定第二个参数的endIndex – 1。 示例 输出结果

  • 问题内容: 使用Play Framework,我通过GSON序列化了模型。我指定哪些字段是公开的,哪些不是。 这很好用,但我也想使用@expose方法。当然,这太简单了。 我该怎么做 ? 谢谢你的帮助 ! 问题答案: 我遇到的最好的解决方案是制作一个专用的序列化器: 并在我看来像这样使用它: 但是为某个方法工作会很棒:它将避免使序列化器仅用于显示方法!