Python 之队列(queue)的创建、数据进出及线程间使用

2024-05-02 13:08

本文主要是介绍Python 之队列(queue)的创建、数据进出及线程间使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

____tz_zs

队列(queue),是线程间最常用的交换数据的形式,用来在生产者和消费者线程之间的信息传递,是适用于多线程编程的先进先出的数据结构。

一、创建队列对象

1、FIFO 队列(first-in,first-out 先进先出)

class queue.Queue(maxsize=0)
maxsize:(可选参数,默认为 0)用于设定队列长度。maxsize 小于等于 0 则表示队列长度无限。 一旦队列长度达到其设定上限,插入会导致阻塞,直到队列中的数据被消费掉。

2、LIFO 队列(last-in,first-out 后进先出)

class queue.LifoQueue(maxsize=0)
maxsize:(可选参数,默认为 0)用于设定队列长度。maxsize 小于等于 0 则表示队列长度无限。 一旦队列长度达到其设定上限,插入会导致阻塞,直到队列中的数据被消费掉。

3、优先级队列

class queue.PriorityQueue(maxsize=0)

二、往队列中添加项目(Queue.put)

将一个 item 放入队列。

Queue.put(item, block=True, timeout=None)

参数:
tiem:将要放入队列中的对象。
block:可选,说明是否阻塞。
timeout:可选,指定等待时间。

  • 如果可选参数 block 为 true 并且 timeout 为None(即默认值),则在队列没有空闲空间时阻塞,永远等待下去,直到有空闲空间时放入数据。
  • 如果可选参数 block 为 true 并且 timeout 是正数,则在队列没有空闲空间时阻塞,它最多会阻塞 timeout 秒,如果超出了这个时间仍然没有空闲空间,则会抛出 queue.Full 异常。
  • 如果可选参数 block 为 true ,则在队列有空闲空间时立即将数据放入队列中,如果没有空闲空间则立刻抛出 queue.Full 异常(在这种情况下忽略参数 timeout)。

ps:
Queue.put_nowait(item) 等同于 put(item, False)

三、从队列中取出数据(Queue.get)

从队列中移除并返回一个 item。

Queue.get(block=True, timeout=None)

参数:
block:可选,说明是否阻塞。
timeout:可选,指定等待时间。

  • 如果可选参数 block 为 true 并且 timeout 为None(即默认值),则在队列中没有数据时阻塞,永远等待下去,直到队列中有数据可以获取。
  • 如果可选参数 block 为 true 并且 timeout 是正数,则在队列中没有数据时阻塞,它最多会阻塞 timeout 秒,如果超出了这个时间而队列中仍然没有数据,则会抛出 queue.Empty 异常。
  • 如果可选参数 block 为 true ,则在队列有数据时立即取出,如果没有数据则立刻抛出 queue.Empty 异常(在这种情况下忽略参数 timeout)。

ps:
Queue.get_nowait() 相当于 get(False) 。

四、Queue.join() 和 Queue.task_done() 的使用

  • 每当有 item 被 put 到队列时,未完成任务的计数(Queue 对象 的 unfinished_tasks 属性)就会加 1。
  • 每当调用 task_done()方法时,计数就会减 1。当未完成任务的数量降至 0 时,Queue.join()的阻塞消失。

例1:队列中存储了三个 item,在线程结束时队列随之消失。

# -*- coding:utf-8 -*-
"""
@author: tz_zs
"""import queueq = queue.Queue()
print("队列大小:%s" % q.qsize())  # 队列大小
print("未完成的任务数:%s" % q.unfinished_tasks)  # 未完成的任务数q.put(222)
q.put(333)
q.put(444)print("队列大小:%s" % q.qsize())  # 队列大小
print("未完成的任务数:%s" % q.unfinished_tasks)  # 未完成的任务数print("结束")"""
队列大小:0
未完成的任务数:0
队列大小:3
未完成的任务数:3
结束Process finished with exit code 0
"""

例2:队列中存入三个 item,未完成任务的计数为3,未处理完,所以进程阻塞在 Queue.join() 处。

# -*- coding:utf-8 -*-
"""
@author: tz_zs
"""import queueq = queue.Queue()
print("队列大小:%s" % q.qsize())  # 队列大小
print("未完成的任务数:%s" % q.unfinished_tasks)  # 未完成的任务数q.put(222)
q.put(333)
q.put(444)print("队列大小:%s" % q.qsize())  # 队列大小
print("未完成的任务数:%s" % q.unfinished_tasks)  # 未完成的任务数q.join()
print("结束")"""
队列大小:0
未完成的任务数:0
队列大小:3
未完成的任务数:3
"""

例3:队列中存入三个 item,未完成任务的计数为3。虽然已通过 Queue.get() 取出,但计数并没有减少,进程仍阻塞在 Queue.join() 处。

# -*- coding:utf-8 -*-
# -*- coding:utf-8 -*-
"""
@author: tz_zs
"""import queueq = queue.Queue()
print("队列大小:%s" % q.qsize())  # 队列大小
print("未完成的任务数:%s" % q.unfinished_tasks)  # 未完成的任务数q.put(222)
q.put(333)
q.put(444)
q.get()
q.get()
q.get()print("队列大小:%s" % q.qsize())  # 队列大小
print("未完成的任务数:%s" % q.unfinished_tasks)  # 未完成的任务数q.join()
print("结束")"""
队列大小:0
未完成的任务数:0
队列大小:0
未完成的任务数:3
"""

例4:队列中存入三个 item,未完成任务的计数为3。通过调用 Queue.task_done() 将计数减少到 0,线程未阻塞。

# -*- coding:utf-8 -*-
"""
@author: tz_zs
"""import queueq = queue.Queue()
print("队列大小:%s" % q.qsize())  # 队列大小
print("未完成的任务数:%s" % q.unfinished_tasks)  # 未完成的任务数q.put(222)
q.put(333)
q.put(444)
q.task_done()
q.task_done()
q.task_done()print("队列大小:%s" % q.qsize())  # 队列大小
print("未完成的任务数:%s" % q.unfinished_tasks)  # 未完成的任务数q.join()
print("结束")"""
队列大小:0
未完成的任务数:0
队列大小:3
未完成的任务数:0
结束Process finished with exit code 0
"""

五、队列大小的相关属性和方法

1、Queue.qsize()

返回队列的大致大小。注意,qsize() > 0 不保证后续的 get() 方法不被阻塞,qsize() < maxsize 也不保证 put() 方法不被阻塞。

2、Queue.empty()

如果队列为空,返回 True ,否则返回 False 。如果 empty() 返回 True ,不保证后续调用的 put() 不被阻塞。类似的,如果 empty() 返回 False ,也不保证后续调用的 get() 不被阻塞。

3、Queue.full()

如果队列是满的返回 True ,否则返回 False 。如果 full() 返回 True 不保证后续调用的 get() 不被阻塞。类似的,如果 full() 返回 False 也不保证后续调用的 put() 不被阻塞。

4、Queue.maxsize

属性,创建队列时传入参数,代表队列的最大容量,小于等于 0 代表无线。

5、Queue.queue

# -*- coding:utf-8 -*-
"""
@author: tz_zs
"""import queueq = queue.Queue()q.put(222)
q.put(333)
q.put(444)
dq = q.queue  # deque([222, 333, 444])
print(dq)
l = list(dq)  # <class 'list'>: [222, 333, 444]
print(l)
"""
deque([222, 333, 444])
[222, 333, 444]
"""

六、官网例子:如何等待排队的任务被完成的示例

def worker():while True:item = q.get()if item is None:breakdo_work(item)q.task_done()q = queue.Queue()
threads = []
for i in range(num_worker_threads):t = threading.Thread(target=worker)t.start()threads.append(t)for item in source():q.put(item)# block until all tasks are done
q.join()# stop workers
for i in range(num_worker_threads):q.put(None)
for t in threads:t.join()

这篇关于Python 之队列(queue)的创建、数据进出及线程间使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/954316

相关文章

Linux线程同步/互斥过程详解

《Linux线程同步/互斥过程详解》文章讲解多线程并发访问导致竞态条件,需通过互斥锁、原子操作和条件变量实现线程安全与同步,分析死锁条件及避免方法,并介绍RAII封装技术提升资源管理效率... 目录01. 资源共享问题1.1 多线程并发访问1.2 临界区与临界资源1.3 锁的引入02. 多线程案例2.1 为

Django开发时如何避免频繁发送短信验证码(python图文代码)

《Django开发时如何避免频繁发送短信验证码(python图文代码)》Django开发时,为防止频繁发送验证码,后端需用Redis限制请求频率,结合管道技术提升效率,通过生产者消费者模式解耦业务逻辑... 目录避免频繁发送 验证码1. www.chinasem.cn避免频繁发送 验证码逻辑分析2. 避免频繁

批量导入txt数据到的redis过程

《批量导入txt数据到的redis过程》用户通过将Redis命令逐行写入txt文件,利用管道模式运行客户端,成功执行批量删除以Product*匹配的Key操作,提高了数据清理效率... 目录批量导入txt数据到Redisjs把redis命令按一条 一行写到txt中管道命令运行redis客户端成功了批量删除k

Java使用Thumbnailator库实现图片处理与压缩功能

《Java使用Thumbnailator库实现图片处理与压缩功能》Thumbnailator是高性能Java图像处理库,支持缩放、旋转、水印添加、裁剪及格式转换,提供易用API和性能优化,适合Web应... 目录1. 图片处理库Thumbnailator介绍2. 基本和指定大小图片缩放功能2.1 图片缩放的

精选20个好玩又实用的的Python实战项目(有图文代码)

《精选20个好玩又实用的的Python实战项目(有图文代码)》文章介绍了20个实用Python项目,涵盖游戏开发、工具应用、图像处理、机器学习等,使用Tkinter、PIL、OpenCV、Kivy等库... 目录① 猜字游戏② 闹钟③ 骰子模拟器④ 二维码⑤ 语言检测⑥ 加密和解密⑦ URL缩短⑧ 音乐播放

python panda库从基础到高级操作分析

《pythonpanda库从基础到高级操作分析》本文介绍了Pandas库的核心功能,包括处理结构化数据的Series和DataFrame数据结构,数据读取、清洗、分组聚合、合并、时间序列分析及大数据... 目录1. Pandas 概述2. 基本操作:数据读取与查看3. 索引操作:精准定位数据4. Group

Python pandas库自学超详细教程

《Pythonpandas库自学超详细教程》文章介绍了Pandas库的基本功能、安装方法及核心操作,涵盖数据导入(CSV/Excel等)、数据结构(Series、DataFrame)、数据清洗、转换... 目录一、什么是Pandas库(1)、Pandas 应用(2)、Pandas 功能(3)、数据结构二、安

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

Python安装Pandas库的两种方法

《Python安装Pandas库的两种方法》本文介绍了三种安装PythonPandas库的方法,通过cmd命令行安装并解决版本冲突,手动下载whl文件安装,更换国内镜像源加速下载,最后建议用pipli... 目录方法一:cmd命令行执行pip install pandas方法二:找到pandas下载库,然后

MySQL中EXISTS与IN用法使用与对比分析

《MySQL中EXISTS与IN用法使用与对比分析》在MySQL中,EXISTS和IN都用于子查询中根据另一个查询的结果来过滤主查询的记录,本文将基于工作原理、效率和应用场景进行全面对比... 目录一、基本用法详解1. IN 运算符2. EXISTS 运算符二、EXISTS 与 IN 的选择策略三、性能对比