微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

当在greenlet主greenlet除外内调用queue.get时,gevent队列不会引发Empty?

如何解决当在greenlet主greenlet除外内调用queue.get时,gevent队列不会引发Empty?

我对 gevent 很陌生,我的问题甚至可能很幼稚,但是当我运行以下代码时,我得到队列空异常。

案例 1 有意义

import gevent
from gevent import monkey
monkey.patch_all()

q = gevent.queue.Queue(maxsize=10)

try:
    q.get(timeout=1)
except gevent.queue.Empty:
    print("main greenlet queue empty")

但是如果我运行下面的代码,我不会得到任何超时,代码只是从不调用任何异常,我从不进入异常处理块,实际上代码甚至不会等待 1 秒从队列中获取数据。我只是立即执行显示输出

案例 2

import gevent
from gevent import monkey
monkey.patch_all()

q = gevent.queue.Queue(maxsize=10)

def worker(idx):
    print("worker",idx)
    try:
        q.get(timeout=1)
    except gevent.queue.Empty:
        print("worker",idx,"queue empty")

workers = [gevent.spawn(worker,i) for i in range(1)]

这个输出

worker 0

但是,如果我在主 greenlet 中调用 get 并在 child 和 main greenlet 中调用 queue.get 如下所示,行为现在会恢复正常。

案例 3

import gevent
from gevent import monkey
monkey.patch_all()

q = gevent.queue.Queue(maxsize=10)

def worker(idx):
    print("worker",i) for i in range(1)]

try:
    q.get(timeout=1)
except gevent.queue.Empty:
    print("main greenlet queue empty")

我得到以下输出

worker 0
main greenlet queue empty
worker 0 queue empty

我不明白为什么情况 2 不会引发异常,有人可以向我解释我做错了什么吗?

我正在使用 python 3.7 和 gevent '21.1.2'

解决方法

在您的第二种情况下,您正在启动 greenlets(解释器在此之后退出)。添加 joinall() 会使您的代码等待生成的 greenlets 返回:

q = gevent.queue.Queue(maxsize=10)

def worker(idx):
    print("worker",idx)
    try:
        q.get(timeout=1)
    except gevent.queue.Empty:
        print("worker",idx,"queue empty")


print(q.empty())
workers = [gevent.spawn(worker,i) for i in range(1)]
# waiting for them to finish,works as expected!
gevent.joinall(workers)

出:

True
worker 0
worker 0 queue empty

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。