queue模块:消息安全地在多线程间交换,实现了多生产者、多消费者队列
看源码 queue 模块包含四个实用的类:
一、三种队列:
1、Queue()、SimpleQueue():先进先出队列
2、LifoQueue():先进后出队列
3、PriorityQueue():优先级队列,优先级编号,按ascii码表的顺序从小到大输出
数据格式:(优先级编号,数据)
二、四个类的实例化方法:
- Queue():默认0,小于等于0无限长度;Queue(5)-长度为 5 的队列
- SimpleQueue():无参数,无限长度
- LifoQueue():继承Queue类,和Queue实例化一样
- PriorityQueue():继承Queue类,和Queue实例化一样
三、四个类的方法
1、Queue() 先进先出
from queue import Queueque = Queue()que.empty() # 队列为空,返回 True,否则返回 Falseque.full() # 队列设置长度时,满了返回 True,否则 Falseque.qsize() # 返回队列的长度# 写入队列4种方式que.put(1)# 解读:1、等价于 que.put(1,block=True,timeout=None)# 2、阻塞写入:队列满了阻塞,一直等到不满的时候再写入,不报错que.put(1,timeout=1)# 解读:1、等价于 que.put(1,block=True,timeout=1)# 2、阻塞写入:队列满了阻塞,阻塞超过1秒,报错 queue.Fullque.put(1,block=False) # 非阻塞时 timeout 参数无效# 解读:1、等价于 que.put(1,block=False,timeout=None)# 2、非阻塞写入:队列满了,立即报错 queue.Fullque.put_nowait()# 解读:1、等价于 que.put(1,block=False)# 2、非阻塞写入:队列满了,立即报错 queue.Full# 读取队列4种方式que.get() # 获取队列数据# 解读:1、等价于 que.get(block=True,timeout=None)# 2、阻塞获取:队列空了阻塞,一直等到不为空时再读取,不报错que.get(timeout=1)# 解读:1、等价于 que.get(block=True,timeout=1)# 2、阻塞获取:队列空了阻塞,阻塞超过1秒,报错 _queue.Emptyque.get(block=False) # 非阻塞时 timeout 参数无效# 解读:1、等价于 que.get(block=False,timeout=None)# 2、非阻塞获取:队列空了,立即报错 _queue.Emptyque.get_nowait()# 解读:等价于 que.get(block=False)# 2、非阻塞获取:队列空了,立即报错 _queue.Empty# jion 和 task_done 一般配合使用,看生产者和消费者模型示例que.join()# 解读:1、一般用于生产者线程,put 后阻塞线程,直到 task_done 解除阻塞,生产者线程才会继续运行# 2、必须配合消费者线程 task_done 解除阻塞,否则生产者线程会一直阻塞下去que.task_done()# 解读:1、用于消费者线程,get 后使用 task_done,直到队列为空时,解除阻塞# 2、一个消费者线程 task_done 一次,只能解除一个生产者线程的 join 阻塞
2、SimpleQueue() 先进先出
from queue import SimpleQueueque = SimpleQueue()que.empty() # 等同于Queue()的empty() que.qsize() # 等同于Queue()的qsize()# que.full() # 简单的队列没有这个方法,因为队列无限长度,不可能满# 写入队列2种方式(无限长度时,写入无阻塞模式,也不会超时)que.put(1) # 立即写入,block 和 timeout 参数无效que.put_nowait(1) # 等价于 que.put(1)que.get() # 等同于Queue()的get()# que.task_done() # 简单的队列没有这个方法,不提供功能# que.join() # 简单的队列没有这个方法,不提供功能
3、LifoQueue() 先进后出
from queue import LifoQueueque = LifoQueue()# 方法和用法等同于 Queue()
4、PriorityQueue() 按ascii码表的顺序取出
from queue import PriorityQueueque = PriorityQueue()que.put([2,'b'])# put数据格式1:元组(优先级编号,数据) # put数据格式2:列表[优先级编号,数据]# 方法和用法等同于 Queue()
四、生产者、消费者模型
1、边生产,边消费;可多生产者线程,多消费者线程
2、生产1个,消费1个(join、task_done配合)
备注:threading.current_thread().name # 获取线程名称
3、2个生产者线程,1个消费者线程
备注:threading.current_thread().name # 获取线程名称
五、特别说明:
先进先出:Queue()、SimpleQueue() 都可以
- 如果不限制队列长度,且不用阻塞模式,SimpleQueue() 完全够用了
- SimpleQueue 没有高级方法 join() 和 task_done()