程序员求职经验分享与学习资料整理平台

网站首页 > 文章精选 正文

python线程之七:线程间通信queue,最全、最明白阐述

balukai 2025-03-01 12:51:34 文章精选 4 ℃

queue模块:消息安全地在多线程间交换,实现了多生产者、多消费者队列

看源码 queue 模块包含四个实用的类:


一、三种队列:

1、Queue()、SimpleQueue():先进先出队列



2、LifoQueue():先进后出队列



3、PriorityQueue():优先级队列,优先级编号,按ascii码表的顺序从小到大输出

数据格式:(优先级编号,数据)

二、四个类的实例化方法:

  1. Queue():默认0,小于等于0无限长度;Queue(5)-长度为 5 的队列
  2. SimpleQueue():无参数,无限长度
  3. LifoQueue():继承Queue类,和Queue实例化一样
  4. 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()
最近发表
标签列表