并发编程-线程
并发编程-线程
- 一个进程是操作系统中运行的一个任务,进程独立拥有CPU、内存等资源
- 一个线程是一个进程中运行的一个任务,线程之间共享CPU、内存等资源,进程里的每一个任务都是线程。
线程创建
创建线程:使用threading模块中的Thread类来创建线程
- target表示线程执行的任务
- args表示任务的参数,是一个元组
- start()方法指启动线程
- join()方法指等待线程结束
from threading import Threaddef task(count:int):...thread1 = Thread(target=task, args=(10,)) # 创建子线程thread1
thread1.start() # 启动子线程
启动两个线程执行task任务
from threading import Threaddef task(count: int):for i in range(count):print(i)thread1 = Thread(target=task, args=(10,))
thread2 = Thread(target=task, args=(20,))thread1.start() # 启动线程1
thread2.start() # 启动线程2
print("main thread is end") # 执行到此处,主线程无任务,自行结束
输出结果:
0
1
2
3
4
5
06main thread is end78
9
1
2
3
4
5
6
7
8
9
等待主线程结束:
from threading import Threaddef task():for i in range(10):print(i)thread1 = Thread(target=task)
thread2 = Thread(target=task)thread1.start()
thread2.start()
thread1.join() # 等待线程执行结束
thread2.join() # 等待线程执行结束
print("main thread is end") # 等到线程1和线程2任务执行完毕,主线程才会结束
输出结果:
0
1
2
3
4
50
6
7
8
9
12
3
4
5
6
7
8
9
main thread is end
通过继承创建线程
通过继承Thread类来创建线程
打印混乱的原因:多线程执行时,print函数打印内容后会再打印换行,导致换行来不及打印,出现打印混乱
解决办法:行尾手动加换行,print函数end参数设置为空字符串
print(f"{self.name} - {i}\n", end="")
from threading import Threadclass MyThread(Thread):def run(self) -> None:# 线程的任务脚本pass
import time
from threading import Threadclass MyThread(Thread):def __init__(self, name: str, count: int):super().__init__()# 该方法已弃用,使用name属性替换# self.setName()self.name = name # 设置线程名称self.count = countdef run(self) -> None:# 线程的任务脚本for i in range(self.count):print(f"{self.name} - {i}\n", end="")# 休眠10毫秒time.sleep(0.01)t1 = MyThread("a", 10)
t2 = MyThread("b", 10)
t1.start()
t2.start()
输出结果:
D:\Python3.11\python.exe F:/Code/python_code/high_python/python_advance/thread/demo01_class.py
a - 0
b - 0
a - 1
b - 1
b - 2
a - 2
a - 3
b - 3
b - 4
a - 4
b - 5
a - 5
b - 6
a - 6
b - 7
a - 7
b - 8
a - 8
b - 9
a - 9
守护线程
主线程结束,守护线程会自动结束,这就叫守护线程
- 守护线程会在主线程结束时候自动结束
- 主线程则需要等待到所有的非守护线程结束才能结束
- 守护线程一般用于非关键性的线程,比如:日志
from threading import Threaddef task():for i in range(10):print(i)thread = Thread(target=task, daemon=True)
thread.start()
输出结果:
0
Process finished with exit code 0
等待线程结束
from threading import Threaddef task():for i in range(10):print(i)thread = Thread(target=task, daemon=True)
thread.start()
thread.join()
输出结果:
D:\Python3.11\python.exe F:/Code/python_code/high_python/python_advance/thread/demo03_daemon_thread.py
0
1
2
3
4
5
6
7
8
9Process finished with exit code 0
继承类设置守护线程
class MyThread(Thread):def __init__(self, name: str, count: int):super().__init__()# 该方法已弃用,使用name属性替换# self.setName()self.name = name # 设置线程名称self.count = countself.daemon = Truedef run(self) -> None:# 线程的任务脚本for i in range(self.count):print(f"{self.name} - {i}\n", end="")# 休眠10毫秒time.sleep(0.01)t1 = MyThread("a", 10)
t2 = MyThread("b", 10)
t1.start()
t2.start()
t1.join() # 等待t1结束,结束主线程
线程安全队列
queue模块中的Queue类提供了线程安全队列功能
- put(item, block=False) # 队列元素满时,不阻塞,会抛出异常,为True时,会让线程阻塞等待, 可能会导致线程卡死
- put(item, timeout=3) # 队列元素满时,等待timeout时间,如果超出时间则抛出异常
- get(block=False) # 从队列取元素,如果队列为空则不阻塞,会抛出异常
- get(timeout=10) # 从队列取元素,如果队列为空则则赛等待10秒,超时抛出异常
- qsize() # 队列大小
- empty() # 判断队列是否为空
- full() # 判断队列是否满的
生产者消费者线程实例
from threading import Thread
from queue import Queueclass Producer(Thread):"""生产者"""def __init__(self, name: str, count: int, queue: Queue) -> None:super(Producer, self).__init__()# 线程自带属性self.name = name# 自定义属性self.count = countself.queue = queuedef run(self) -> None:for n in range(self.count):msg = f"{self.name} - {n}"self.queue.put(msg, block=True)class Consumer(Thread):"""消费者"""def __init__(self, name: str, queue: Queue) -> None:super().__init__()self.name = nameself.daemon = Trueself.queue = queuedef run(self) -> None:while True:msg = self.queue.get(block=True)print(f"{self.name} - {msg}\n", end="")queue = Queue(maxsize=3)
threads = [Producer("p1", 10, queue),Producer("p2", 10, queue),Producer("p3", 10, queue),Consumer("c1", queue),Consumer("c2", queue),
]for t in threads:t.start()
线程池
- 线程的创建和销毁相对比较耗费资源
- 频繁的创建和销毁线程不利于高性能
- 线程池是python提供的便于线程管理和提高性能的工具
python提供两个类来管理线程
concurrent.futures.ThreadPoolExecutor
- submit() # 启动/执行一个任务,返回结果是一个Future对象
- map() # 多个任务执行,将不同参数分配到每一个任务中
- shutdown() # 关闭线程池
- Future
- result() # 任务执行结果
- exception() # 任务异常信息
方式一:适用于不同任务
from concurrent.futures import ThreadPoolExecutor
import timedef task(name: str):print(f"{name} - step 1\n", end="")time.sleep(1)print(f"{name} - step 2\n", end="")return f"{name} complete"with ThreadPoolExecutor() as executor:result_1 = executor.submit(task, "A")result_2 = executor.submit(task, "B")print(result_1.result()) # result()会等待有结果再返回print(result_2.result())"""
A - step 1
B - step 1
A - step 2
A complete
B - step 2
B complete
"""
方式二:map()
适用于同一任务,不同参数
from concurrent.futures import ThreadPoolExecutor
import timedef task(name: str) -> str:print(f"{name} - step 1\n", end="")time.sleep(1)print(f"{name} - step 2\n", end="")return f"{name} complete"with ThreadPoolExecutor() as executor:results = executor.map(task, ["C", "D"])for r in results:print(r)"""
C - step 1
D - step 1
D - step 2
C - step 2
C complete
D complete
"""
多线程案例:下载图片
from concurrent.futures import ThreadPoolExecutor
from urllib.request import urlopen, Request
import osdef download_img(url: str):site_url = Request(url, headers={})with urlopen(site_url) as web_file:img_data = web_file.read()if not img_data:raise Exception(f"Error: can not load the image from {url}")file_name = os.path.basename(url)with open(file_name, "wb") as f:f.write(img_data)return "Download image successfully, {}".format(url)urls = ["https://img0.bdstatic.com/static/searchresult/img/baseimg3_4f26a23.png",# "..."
]
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36","content-type": "Content-Type: image/jpeg"
}
with ThreadPoolExecutor() as ececutor:results = ececutor.map(download_img, urls)for r in results:print(r)
执行结果:
PS F:\Code\python_code\high_python\python_advance\thread> python .\thread_pool_demo.py
Download image successfully, https://img0.bdstatic.com/static/searchresult/img/baseimg3_4f26a23.png
相关文章:
并发编程-线程
并发编程-线程 一个进程是操作系统中运行的一个任务,进程独立拥有CPU、内存等资源一个线程是一个进程中运行的一个任务,线程之间共享CPU、内存等资源,进程里的每一个任务都是线程。 线程创建 创建线程:使用threading模块中的Th…...

图解LeetCode——剑指 Offer 34. 二叉树中和为某一值的路径
一、题目 给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。叶子节点 是指没有子节点的节点。 二、示例 2.1> 示例 1: 【输入】root [5,4,8,11,null,13,4,7,2,null,null,5,1], t…...

使用Python免费试用最新Openai API
一、背景介绍 3月2日凌晨,OpenAI放出了真正的ChatGPT API,不是背后的GPT-3.5大模型,是ChatGPT的本体模型!ChatGPT API价格为1k tokens/$0.002,等于每输出100万个单词,价格才2.7美金(约18元人民…...

04、启动 SVN 服务器端程序
启动 SVN 服务器端程序1 概述2 用命令行单项目启动2.1 采用 svnserve 命令2.2 验证服务是否启动2.3 命令行方式的缺陷3 注册Windows服务3.1 注册服务的命令3.2 命令说明3.3 启动服务1 概述 SVN 服务器和 Tomcat 服务器,Nexus 服务器一样, 必须处于运行状态才能响应…...

jsp船舶引航计费网站Myeclipse开发mysql数据库web结构java编程计算机网页项目
一、源码特点 JSP船舶引航计费网站是一套完善的java web信息管理系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql5.0&…...

Allegro如何画半圆形的线操作指导
Allegro如何画半圆形的线操作指导 在用Allegro设计PCB的时候,在某些应用场合会需要画半圆形,如下图 如何画半圆形,具体操作如下 点击Add点击Arc w/Radius...

【强烈建议收藏:MySQL面试必问系列之SQL语句执行专题】
一.知识回顾 之前的文章我们一起学习了MySQL面试必问系列之事务专题、锁专题,没有学习的小伙伴可以直接通过该链接地址直接访问,MYSQL你真的了解吗专栏的文章,接下来我们就一起来学习一下MySQL中SQL语句的执行流程,看看你掌握的怎…...
详解Linux下的环境变量以及C++库文件和头文件、python库的配置
目录 Linux环境变量配置基本步骤 1.查看环境变量 2.设置环境变量 3.永久性设置环境变量 4.使用环境变量 C 库文件和头文件环境变量配置 1.配置so库文件的环境变量 2.配置头文件的环境变量 Python库环境变量配置 Linux配置执行文件环境变量 我们都习惯在Windows 上配置…...

企业级分布式数据库 - GaussDB介绍
目录 什么是GaussDB 简介 应用场景 产品架构 产品优势 安全 责任共担 身份认证与访问控制 数据保护技术 审计与日志 监控安全风险 故障恢复 认证证书 GaussDB与其他服务的关系 约束与限制 计费模式 什么是GaussDB …...

Linux I2C 驱动实验
目录 一、Linux I2C 驱动简介 1、I2C 总线驱动 2、I2C 设备驱动 1、 i2c_client 结构体 2、 i2c_driver 结构体 二、硬件分析 三、设备树编写 1、pinctrl_i2c1 2、在 i2c1 节点追加 ap3216c 子节点 3、验证 四、 代码编写 1、makefile 2、ap3216c.h 3、ap3216c.c …...

DC-DC模块电源隔离直流升压高压稳压输出5v12v24v转60v100v110v150v220v250v300v400v500v
特点效率高达80%以上1*1英寸标准封装单电压输出稳压输出工作温度: -40℃~85℃阻燃封装,满足UL94-V0 要求温度特性好可直接焊在PCB 上应用HRB 0.2~10W 系列模块电源是一种DC-DC升压变换器。该模块电源的输入电压分为:4.5~9V、9~18V、及18~36VDC标准&#…...
EF有几种模式,EF的三种模式分别是什么?
EF有几种模式,EF的三种模式分别是什么? 第一种:DataBase First DataBase First传统的表驱动方式创建EDM,然后通过EDM生成模型和数据层代码。除生成实体模型和自跟踪实现模型,还支持生成轻型DbContext。 解释…...

数据可视化展示:打工人常见职业病,颈腰椎病占比最高达66.51%
身体健康才是一切的根本。只有身体健健康康才能更好的去享受世间的美好,无论是谁都应当注重身体健康,而不是无度的挥霍它! 良好的身体,释放给工作,健壮的体魄,享受美好生活,良好的心态ÿ…...

【食品图像识别】Large Scale Visual Food Recognition
1 引言 视觉智能部与中科院计算所于2020-2021年度展开了《细粒度菜品图像识别和检索》科研课题合作,本文系双方联合在IEEE T-PAMI2023发布论文《Large Scale Visual Food Recognition》 (Weiqing Min, Zhiling Wang, Yuxin Liu, Mengjiang Luo, Liping Kang, Xiaom…...

RAN-in-the-Cloud:为 5G RAN 提供云经济性
RAN-in-the-Cloud:为 5G RAN 提供云经济性 5G 部署在全球范围内一直在加速。 许多电信运营商已经推出了5G服务并正在快速扩张。 除了电信运营商之外,企业也对使用 5G 建立私有网络产生了浓厚的兴趣,这些私有网络利用了更高的带宽、更低的延迟…...
vector、list、queue
引用:windows程序员面试指南 vector vector 类似于C语言中的数组 vector 支持随机访问,访问某个元素的时间复杂度 O(1) vector 插入和删除元素效率较低,时间复杂度O(n) vector 是连续存储,没有内存碎片,空间利用率高…...
操作系统面经
进程与线程区别 1.进程是资源分配的最小单位,线程是程序执行的最小单位(资源调度的最小单位) 2.进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数…...

一天约了4个面试,复盘一下面试题和薪资福利
除了最新的面经分享,还有字节大佬的求职面试答疑,告诉你关键问题是什么?少走弯路。**另外本文也汇总了6份大厂面试题:字节、腾讯、小米、腾讯云、滴滴、小米游戏。**希望对大家有帮助。 前言 昨天我的交流群里,有位宝…...

详解单链表(内有精美图示哦)
全文目录引言链表链表的定义与结构链表的分类单链表的实现及对数据的操作单链表的创建与销毁创建销毁单链表的打印单链表的头插与头删头插头删单链表的尾插与尾删尾插尾删单链表的查找单链表在pos位置后插入/删除插入删除单链表在pos位置插入/删除插入删除总结引言 在上一篇文…...
csdn文章导航
这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注…...

从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

mac 安装homebrew (nvm 及git)
mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用: 方法一:使用 Homebrew 安装 Git(推荐) 步骤如下:打开终端(Terminal.app) 1.安装 Homebrew…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...

FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...