协程启动后会按照添加到循环的顺序开始执行,上例在队列未满之前一直执行put操作,直到队列满后阻塞就切换到put2协程,也会立即阻塞,然后切换到get1协程,获取所有的值直到队列为空后阻塞切换。
gevent.queue.Queue对象其方法基本和Queue.Queue的方法相同,特殊方法如下:
q = Queue(9, items=[1,2,3, StopIteration]) # 实现迭代协议,最后一个必须是StopIteration # q.copy() #复制一个队列 x = q.next() # 唤醒获取值 q.peek(block=True, timeout=None) # 获取一个值但是不删除它 q.peek_nowait() # 立即获取,忽略timeout q.put() # 会唤醒多个协程完成添加操作 q.get() # 会挂起多个协程gevent.queue.JoinableQueue对象扩展了Queue的功能,添加了task_done和join方法。
q = JoinableQueue(9, items=[1,2,3, StopIteration]) # 这个Queue可以在多个进程之间共享 q.task_done() # 通知队列一个任务完成 q.unfinished_tasks # 未完成的任务计数 q.join() # 阻塞等待任务完成,如果unfinished_tasks降为0,则解除实例
from gevent.queue import Queue, JoinableQueue import gevent import time def get_from_queue(queue:JoinableQueue): while True: try: x = queue.get() # 阻塞时就会切换协程 print(x) finally: queue.task_done() if __name__ == \'__main__\': q = JoinableQueue(8) job1 = [gevent.spawn(get_from_queue, q) for i in range(2)] for i in range(100): q.put(i) # 当Put被阻塞时将切换协程, q.join() # 如果不等待的话,最后一次put后将直接退出
参考