简体   繁体   English

当在greenlets(除了主greenlet)中调用queue.get时,gevent队列不会引发Empty?

[英]gevent queue does not raise Empty when queue.get invoked inside greenlets (other than the main greenlet)?

I am very new to gevent and my question might even be very naive, but the when I run following code I get queue empty exception.我对 gevent 很陌生,我的问题甚至可能很幼稚,但是当我运行以下代码时,我得到队列空异常。

case 1 makes sense案例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")

but if I run following code I do not get any timeout and code just never invokes any exceptions and I never enter the exception handeling block, in fact code doesn't even wait for 1 sec to fetch data from queue.但是如果我运行以下代码,我不会得到任何超时,并且代码永远不会调用任何异常并且我永远不会进入异常处理块,实际上代码甚至不会等待 1 秒来从队列中获取数据。 I just executes immediately with the shown output.我只是立即使用所示的 output 执行。

case 2案例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)]

this outputs:这输出:

worker 0

However, if I call get in the main greenlet with a call to queue.get in both child and main greenlet like following, the behaviour now changes back to normal.但是,如果我在主greenlet 中调用get 并在子greenlet 和主greenlet 中调用queue.get,如下所示,行为现在会恢复正常。

case 3案例3

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)]

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

I get following output.我关注 output。

worker 0
main greenlet queue empty
worker 0 queue empty

I fail to understand that why does case 2 not raise an exception, can some one please explain to me what am I doing wrong?我不明白为什么案例 2 没有引发异常,有人可以向我解释我做错了什么吗?

I am using python 3.7 and gevent '21.1.2'我正在使用 python 3.7 和 gevent '21.1.2'

In your second case, you are starting greenlets (the interpreter exits after).在第二种情况下,您正在启动 greenlets(解释器在之后退出)。 Adding joinall() makes your code wait for the spawned greenlets to return:添加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)

Out:出去:

True
worker 0
worker 0 queue empty

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM