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

相关文章

Python中你不知道的gzip高级用法分享

《Python中你不知道的gzip高级用法分享》在当今大数据时代,数据存储和传输成本已成为每个开发者必须考虑的问题,Python内置的gzip模块提供了一种简单高效的解决方案,下面小编就来和大家详细讲... 目录前言:为什么数据压缩如此重要1. gzip 模块基础介绍2. 基本压缩与解压缩操作2.1 压缩文

Spring IoC 容器的使用详解(最新整理)

《SpringIoC容器的使用详解(最新整理)》文章介绍了Spring框架中的应用分层思想与IoC容器原理,通过分层解耦业务逻辑、数据访问等模块,IoC容器利用@Component注解管理Bean... 目录1. 应用分层2. IoC 的介绍3. IoC 容器的使用3.1. bean 的存储3.2. 方法注

MySQL 删除数据详解(最新整理)

《MySQL删除数据详解(最新整理)》:本文主要介绍MySQL删除数据的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、前言二、mysql 中的三种删除方式1.DELETE语句✅ 基本语法: 示例:2.TRUNCATE语句✅ 基本语

Python设置Cookie永不超时的详细指南

《Python设置Cookie永不超时的详细指南》Cookie是一种存储在用户浏览器中的小型数据片段,用于记录用户的登录状态、偏好设置等信息,下面小编就来和大家详细讲讲Python如何设置Cookie... 目录一、Cookie的作用与重要性二、Cookie过期的原因三、实现Cookie永不超时的方法(一)

Python内置函数之classmethod函数使用详解

《Python内置函数之classmethod函数使用详解》:本文主要介绍Python内置函数之classmethod函数使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 类方法定义与基本语法2. 类方法 vs 实例方法 vs 静态方法3. 核心特性与用法(1编程客

Python函数作用域示例详解

《Python函数作用域示例详解》本文介绍了Python中的LEGB作用域规则,详细解析了变量查找的四个层级,通过具体代码示例,展示了各层级的变量访问规则和特性,对python函数作用域相关知识感兴趣... 目录一、LEGB 规则二、作用域实例2.1 局部作用域(Local)2.2 闭包作用域(Enclos

Linux中压缩、网络传输与系统监控工具的使用完整指南

《Linux中压缩、网络传输与系统监控工具的使用完整指南》在Linux系统管理中,压缩与传输工具是数据备份和远程协作的桥梁,而系统监控工具则是保障服务器稳定运行的眼睛,下面小编就来和大家详细介绍一下它... 目录引言一、压缩与解压:数据存储与传输的优化核心1. zip/unzip:通用压缩格式的便捷操作2.

Python实现对阿里云OSS对象存储的操作详解

《Python实现对阿里云OSS对象存储的操作详解》这篇文章主要为大家详细介绍了Python实现对阿里云OSS对象存储的操作相关知识,包括连接,上传,下载,列举等功能,感兴趣的小伙伴可以了解下... 目录一、直接使用代码二、详细使用1. 环境准备2. 初始化配置3. bucket配置创建4. 文件上传到os

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

使用Python实现可恢复式多线程下载器

《使用Python实现可恢复式多线程下载器》在数字时代,大文件下载已成为日常操作,本文将手把手教你用Python打造专业级下载器,实现断点续传,多线程加速,速度限制等功能,感兴趣的小伙伴可以了解下... 目录一、智能续传:从崩溃边缘抢救进度二、多线程加速:榨干网络带宽三、速度控制:做网络的好邻居四、终端交互