Python的`queue`模块

队列(Queue)

在Python的queue模块中,Queue类是一个线程安全的队列实现,用于在多线程编程中安全地交换信息。它遵循先入先出(FIFO)的原则。Queue类提供了几种主要的方法:

  • put(item): 将一个项目放入队列中。如果队列已满,则此方法将阻塞,直到队列中有空间可用。
  • get(): 从队列中移除并返回一个项目。如果队列为空,则此方法将阻塞,直到队列中有项目可用。
  • task_done(): 表示之前入队的一个任务已经完成。通常由使用get()的消费者线程调用。每调用一次get(),随后就应该调用一次task_done()来告诉队列该任务已处理完毕。
  • join(): 阻塞调用线程,直到队列中的所有项目都被处理并调用task_done()方法。这通常用于等待由队列消费的所有工作项完成。

并发编程中的线程

在Python中,threading模块提供了基本的线程和锁支持。每个Thread对象代表了一个线程的执行。线程之间共享全局解释器锁(GIL),这意味着在任意时刻只有一个线程可以执行Python字节码。然而,对于I/O密集型任务(如文件读写、网络请求)和等待密集型任务(如数据库查询、外部API调用),多线程仍然可以提高程序的总体性能,因为线程在等待时可以释放GIL,允许其他线程运行。

示例详解

下面是对之前示例的详细解释,包括一些注意事项和潜在的改进点:

import queue
import threading
import time
import randomdef worker(q, job_type):while True:  # 注意:这里的无限循环需要外部机制来中断if job_type == 'producer':item = random.randint(1, 100)q.put(item)print(f'{threading.current_thread().name} 生产了 {item}')time.sleep(random.random())  # 模拟耗时操作elif job_type == 'consumer':item = q.get()print(f'{threading.current_thread().name} 消费了 {item}')time.sleep(random.random())  # 模拟耗时操作q.task_done()  # 告诉队列这个任务已完成# 创建一个队列
q = queue.Queue(maxsize=10)  # 可选地设置队列的最大大小# 创建并启动生产者线程
producers = [threading.Thread(target=worker, args=(q, 'producer'), name=f'生产者-{i+1}') for i in range(2)]
for t in producers:t.daemon = Truet.start()# 创建并启动消费者线程
consumers = [threading.Thread(target=worker, args=(q, 'consumer'), name=f'消费者-{i+1}') for i in range(3)]
for t in consumers:t.daemon = Truet.start()# 注意:由于生产者线程是无限循环的,下面的q.join()将永远不会返回
# 除非有某种机制来停止生产者线程(例如,使用共享变量或threading.Event)
# 为了示例的简洁性,这里省略了停止生产者的代码# 假设我们在某个时刻决定停止所有线程
# 这可以通过设置共享变量或使用threading.Event来实现
# ...(这里省略了停止线程的代码)# 主线程通常不会在这里等待,因为它会立即继续执行后面的代码
# 但为了示例的完整性,我们在这里添加了一个简单的阻塞,以便可以看到一些输出
try:while True:time.sleep(1)
except KeyboardInterrupt:print("主线程被中断,尝试优雅地关闭所有线程...")# 在这里添加关闭所有线程的代码(如果有的话)# 注意:由于我们设置了daemon=True,主线程结束时守护线程也会自动结束# 但这通常不是优雅关闭线程的好方法

注意事项

  1. 无限循环:生产者线程中的无限循环需要外部机制来中断,否则它们将永远运行下去。
  2. 优雅关闭:在实际应用中,你需要实现一种机制来优雅地关闭线程,比如使用共享变量、threading.Eventqueue.Empty异常。
  3. GIL:虽然Python的GIL限制了多线程在CPU密集型任务上的并行性,但它对于I/O密集型任务和等待密集型任务仍然很有用。
  4. 守护线程:在这个示例中,我们使用了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/868148.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

动态规划|剑指 Offer II 093. 最长斐波那契数列

如果数组 arr 中存在三个下标 i、j、k 满足 arr[i]>arr[j]>arr[k] 且 arr[k]arr[j]arr[i],则 arr[k]、arr[j] 和 arr[i] 三个元素组成一个斐波那契式子序列。由于数组 arr 严格递增,因此 arr[i]>arr[j]>arr[k] 等价于 i>j>k。 把这道题…

OPPO手机终极保活方案

Push应用解决CPU休眠应用锁OPPO的电源设置和应用省电设置 要保证OPPO手机的性能足够, 比如内存8G, 否则可能会因为性能不足而被杀死 为了保证长期流畅运行, 应该设置手机定时重启, 比如通过系统设置每天重启, 部分手机不重启会慢慢变卡 需要大量测试去验证方案的普遍性, 就算…

odoo文档的安装

步骤 1: 安装必要的软件 确保你已经安装了Git和Python 3.6、3.7或3.8之一。 步骤 2: 克隆 Odoo 文档存储库 打开终端,然后使用Git克隆Odoo的文档存储库。 git clone https://github.com/odoo/documentation.git cd documentation步骤 3: 安装 Python 依赖项 …

java基础--String字符串对象

一.掌握创建String字符串对象的两种方式 方式一(常用) 在程序中直接写字符串变量,就是一个String对象 String s1 "abc"; System.out.println(s1);注意 : 打印字符串类型的变量,是不会看到字符串对象空间地址值的,底层是有优化的,直接看到字符串对象中存储的内容…

代码随想录-DAY①-数组——leetcode 704 | 27

704 思路 定义查找的范围 [left,right],初始查找范围是整个数组。每次取查找范围的中点 mid,比较 nums[mid] 和 target 的大小,如果相等则 mid 即为要寻找的下标,如果不相等则根据 nums[mid] 和 target 的大小关系将查找范围缩小…

【qt】TCP的监听 (设置服务器IP地址和端口号)

TCP监听是在自己的IP地址上进行的。 当一个TCP服务器程序启动时,它会绑定到一个特定的IP地址和一个端口号上,以便可以接收来自该IP地址和端口号的传入连接请求. 所以我们要先来获取主机的IP地址和设置端口号. 注意: 服务器程序无法任意设置IP地址&…

Java(七)——多态

个人简介 👀个人主页: 前端杂货铺 ⚡开源项目: rich-vue3 (基于 Vue3 TS Pinia Element Plus Spring全家桶 MySQL) 🙋‍♂️学习方向: 主攻前端方向,正逐渐往全干发展 &#x1…

Fortigate 飞塔防火墙CLI – 概述

1,可以通过SSH, Telnet, 或者serial console2,CLI的配置是分级的结构,如下所示:config system interfaceedit "internal"set vdom "root"set ip 192.168.100.99 255.255.255.0set allowaccess p… 1&#xff…

Apipost接口测试工具的原理及应用详解(六)

本系列文章简介: 随着软件行业的快速发展,API(应用程序编程接口)作为不同软件组件之间通信的桥梁,其重要性日益凸显。API的质量直接关系到软件系统的稳定性、性能和用户体验。因此,对API进行严格的测试成为…

Qt | QPen 类(画笔)

01、画笔基础 1、需要使用到的 QPainter 类中的函数原型如下: void setPen(const QPen &pen); //设置画笔,void setPen(const QColor &color); //设置画笔,该笔样式为 Qt::SolidLine、宽度为 1,颜色由 color 指定void setPen(Qt::PenStyle style); //设置画笔,该…

什么是SysTick?

一,滴答定时器SysTick SysTick,即滴答定时器,是内核中一个特殊的定时器,用于提供系统级的定时服务。是一个24位递减计时器,具有自动重载值寄存器的功能 。当计数器到达自动重载值时,它会自动重新加载新的计…

数学基础 -- 复合函数

函数的复合 函数复合是数学中的一个重要概念,指的是将一个函数的输出作为另一个函数的输入。具体来说,给定两个函数 f f f 和 g g g,函数 f f f 和 g g g 的复合记作 f ( g ( x ) ) f(g(x)) f(g(x)) 或 ( f ∘ g ) ( x ) (f \circ g)(…

掌握Vue插槽:创建灵活且可复用的组件

引言 插槽(Slots)是实现组件化的一个强大工具,它允许开发者在组件内部定义可替换的内容区域 插槽的主要作用包括: 内容分发:允许开发者在组件内部定义内容的“插槽”,然后在使用组件时,通过插…

隔离级别-隔离级别中的锁协议、隔离级别类型、隔离级别的设置、隔离级别应用

一、引言 1、DBMS除了采用严格的两阶段封锁协议来保证并发事务的可串行化,实现事务的隔离性,也可允许用户选择一个可以保证应用程序正确执行并且能够使并发度最大的隔离性等级 2、通常用隔离级别来描述隔离性等级,以下将主要介绍ANSI 92标准…

上新:NFTScan 正式上线 Bitcoin-Runes 浏览器!

近日,NFTScan 团队正式对外发布了 Bitcoin-Runes 浏览器,将为 Runes 生态的 NFT 开发者和用户提供简洁高效的 NFT 数据搜索查询服务。Runes 协议的主要目的是定义一种在比特币网络上进行符号化资产交换的方式。它使用 Rune 作为符号化资产的单位&#xf…

【昇思25天学习打卡营打卡指南-第十九天】基于MobileNetv2的垃圾分类

CycleGAN图像风格迁移互换 模型介绍 模型简介 CycleGAN(Cycle Generative Adversarial Network) 即循环对抗生成网络,来自论文 Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks 。该模型实现了一种在没有配对示例的情况下学习…

数据结构学习笔记-十大排序算法

1.插入排序 直接插入排序 //直接插入排序 void InsertSort(int A[], int n){int i,j,temp;for(i1;i<n;i) //将各元素插入已排好序的序列中if(A[i]<A[i-1]){ //若A[i]关键字小于前驱tempA[i]; //用temp暂存A[i]for(ji-1;j>0 && A[j]>temp;--j) …

【大模型LLM面试合集】大语言模型基础_NLP面试题

NLP面试题 1.BERT 1.1 基础知识 BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;是谷歌提出&#xff0c;作为一个Word2Vec的替代者&#xff0c;其在NLP领域的11个方向大幅刷新了精度&#xff0c;可以说是近年来自残差网络最优突破性的…

从零搭建Prometheus到Grafana告警推送

目录 一、Prometheus源码安装和动态更新配置 二、Prometheus操作面板和常见配置 三、Prometheus常用监控组件exporter配置 3.1 exporter是什么 3.2 有哪些exporter 3.3 exporter怎么用 3.4 实战 node_exporter ​3.5 其它exporter都怎么用 四、Promethus整合新版Sprin…

算法mq 交互通用校验模块设计

背景 当前与算法交互均通过rocketMQ异步交互&#xff0c;绝大部分场景一条请求mq消息应对应一条返回mq&#xff0c;但由于各种原因&#xff08;消息积压、程序bug&#xff09;&#xff0c;可能会导致返回mq超时未返回或者消息丢失。工程侧针对一些重要场景 case by case的通过…