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

liftword1个月前 (03-31)技术文章6

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()

相关文章

python笔记47:多线程详解

主要内容:小目标:掌握多线程;主要内容:线程类使用,多线程使用;1. 线程基本概念线程概念:线程是轻量级进程,是操作系统能够进行运算调度的最小单位;线程依赖进程资源,是进程中的实际运作单位;一个进程中...

Python中的多线程详解,让你的程序飞起来!

Python是一门高级编程语言,拥有简单易用、面向对象、可扩展等优点,因此被广泛应用于各种领域。但是在Python中,由于GIL(全局解释器锁)的存在,导致了多线程的效率不高。但是,对于某些IO密集型...

Python并发编程(3)——Python多线程详解介绍

左手编程,右手年华。大家好,我是一点,关注我,带你走入编程的世界。公众号:一点sir,关注领取python编程资料Python 的多线程入门是非常简单的,直接导入threading模块就可以开始多线程...

Python多线程编程到底怎么玩?核心技巧与注意事项全知道!

在 Python 中,多线程编程主要用于处理 I/O 密集型任务(如网络请求、文件读写、数据库操作等),但由于 全局解释器锁(GIL) 的存在,多线程对 CPU 密集型任务 的性能提升有限(此时建议使...

小白都看懂了,Python 中的线程和进程精讲,建议收藏

目录线程和进程一、 什么是进程 / 线程1、 引论众所周知,CPU是计算机的核心,它承担了所有的计算任务。而操作系统是计算机的管理者,是一个大管家,它负责任务的调度,资源的分配和管理,统领整个计算机硬...

Python多线程

本文重点探究以下几个问题:多线程内存共享线程类获取线程结果方法:join/setDaemon对线程退出的作用线程无法利用多核,不是真正的并发多线程内存共享多个线程访问同一内存变量时,需要通过锁机制来实...