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 Queue
que = Queue()
que.empty() # 队列为空,返回 True,否则返回 False
que.full() # 队列设置长度时,满了返回 True,否则 False
que.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.Full
que.put(1,block=False) # 非阻塞时 timeout 参数无效
# 解读:1、等价于 que.put(1,block=False,timeout=None)
# 2、非阻塞写入:队列满了,立即报错 queue.Full
que.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.Empty
que.get(block=False) # 非阻塞时 timeout 参数无效
# 解读:1、等价于 que.get(block=False,timeout=None)
# 2、非阻塞获取:队列空了,立即报错 _queue.Empty
que.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 SimpleQueue
que = 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 LifoQueue
que = LifoQueue()
# 方法和用法等同于 Queue()
4、PriorityQueue() 按ascii码表的顺序取出
from queue import PriorityQueue
que = 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()