我这边遇到一个问题,使用 gevent 的时候,报了 loopexit 的错误。
import random
from Queue import Empty
import gevent
from gevent.queue import *
import gevent.monkey
gevent.monkey.patch_all()
q = Queue()
workers = []
def do_work(wid, value):
gevent.sleep(random.randint(0,2))
print 'Task', value, 'done', wid
return
def worker(wid):
while True:
try:
item = q.get()
if item:
do_work(wid, item)
except StopIteration:
break
except Empty:
break
def producer():
for i in range(4):
workers.append(gevent.spawn(worker, random.randint(1, 888888)))
for item in range(1, 9):
q.put(item)
producer()
gevent.joinall(workers)
我查了网上的资料,看了 gevent 的原理,但是没怎么看明白。网上主流的解释是任务流已经消费完了,协程都在做 waiter 的操作,导致 gevent 的 joinall 失败了。我没有理解这个过程。现在的我的解决办法是,消费完任务之后协程会报空的错误,捕捉一下就退出协程。但是我感觉这样只是掩盖了问题,没有解决问题。
item = q.get() >>item = q.get(block=False)
各位大佬怎么理解 loopexit ?
1
cz5424 2020-11-18 00:05:12 +08:00 via iPhone
感觉是 Queue(),如果想要多线程多进程和协程,一般会避免全局变量
|
2
catxo 2020-11-18 09:50:59 +08:00
你的 worker 是一个循环,没有退出条件
一般都是判断 item 为空作为退出条件 ```python item = q.get() if not item: break do_work(wid, item) ``` producer 里面,加上 ```python for _ in range(4): q.put(None) ``` |