Python的秘密基地--[章节7] Python 并发与多线程编程
第7章:Python 并发与多线程编程
随着计算机硬件的发展,多核处理器已经成为主流。为了更好地利用多核资源,提高程序的运行效率,Python 提供了并发(Concurrency)和并行(Parallelism)编程的工具。本章将深入探讨 Python 中的 线程(Threading)、进程(Multiprocessing) 和 异步编程(Asyncio)。
7.1 并发与并行的区别
- 并发(Concurrency):多个任务交替执行,可能在单核 CPU 上完成,主要关注任务的切换。
- 并行(Parallelism):多个任务同时执行,必须依赖多核 CPU,多个任务真正“同时”运行。
简单理解:
- 并发 → 多个任务在同一时间段内“轮流”执行。
- 并行 → 多个任务在同一时刻“同时”执行。
7.2 多线程(Threading)
7.2.1 什么是线程?
- 线程(Thread) 是操作系统能够进行调度的最小单元。
- Python 提供了
threading模块来实现多线程。 - 注意:由于 GIL(全局解释器锁) 的存在,Python 的多线程无法真正实现并行计算,适合 I/O 密集型任务。
7.2.2 使用 threading 模块
示例:创建多线程
import threading
import timedef task(name):print(f"线程 {name} 开始")time.sleep(2)print(f"线程 {name} 结束")# 创建线程
thread1 = threading.Thread(target=task, args=("线程1",))
thread2 = threading.Thread(target=task, args=("线程2",))# 启动线程
thread1.start()
thread2.start()# 等待线程结束
thread1.join()
thread2.join()print("所有线程已完成")
输出:
线程 线程1 开始
线程 线程2 开始
线程 线程1 结束
线程 线程2 结束
所有线程已完成
7.2.3 线程锁(Lock)
多个线程同时访问共享资源时,可能会导致 数据竞争(Race Condition)。为了解决这个问题,可以使用 线程锁(Lock)。
import threadinglock = threading.Lock()
counter = 0def increment():global counterwith lock: # 上锁temp = countertemp += 1counter = tempthreads = []
for i in range(5):t = threading.Thread(target=increment)threads.append(t)t.start()for t in threads:t.join()print(f"最终计数器值: {counter}")
7.3 多进程(Multiprocessing)
7.3.1 什么是进程?
- 进程(Process) 是操作系统资源分配的基本单位。
- Python 的
multiprocessing模块支持真正的 并行计算,每个进程都有自己的 Python 解释器,不受 GIL 的限制。 - 适合 CPU 密集型任务。
7.3.2 使用 multiprocessing 模块
示例:创建多进程
import multiprocessing
import timedef task(name):print(f"进程 {name} 开始")time.sleep(2)print(f"进程 {name} 结束")if __name__ == "__main__":process1 = multiprocessing.Process(target=task, args=("进程1",))process2 = multiprocessing.Process(target=task, args=("进程2",))process1.start()process2.start()process1.join()process2.join()print("所有进程已完成")
7.3.3 进程池(Pool)
当需要大量进程时,可以使用 进程池(Pool) 管理。
from multiprocessing import Pooldef square(n):return n * nif __name__ == "__main__":with Pool(4) as pool:results = pool.map(square, [1, 2, 3, 4, 5])print(results) # [1, 4, 9, 16, 25]
7.4 异步编程(Asyncio)
7.4.1 什么是异步编程?
- 异步编程是一种 非阻塞 的编程方式。
- 使用
async和await关键字。 - 适合 I/O 密集型任务,例如网络请求、数据库访问等。
7.4.2 异步函数
示例:异步任务
import asyncioasync def task(name):print(f"任务 {name} 开始")await asyncio.sleep(2) # 异步等待print(f"任务 {name} 结束")async def main():await asyncio.gather(task("任务1"),task("任务2"))asyncio.run(main())
输出:
任务 任务1 开始
任务 任务2 开始
任务 任务1 结束
任务 任务2 结束
7.4.3 异步与协程
async:定义异步函数。await:在异步函数内部暂停执行,等待某个异步任务完成。
7.5 并发工具
7.5.1 队列(Queue)
Python 提供了 queue.Queue 和 multiprocessing.Queue 来实现线程间或进程间通信。
import queue
import threadingq = queue.Queue()def producer():for i in range(5):q.put(i)print(f"生产者放入: {i}")def consumer():while not q.empty():item = q.get()print(f"消费者取出: {item}")thread1 = threading.Thread(target=producer)
thread2 = threading.Thread(target=consumer)thread1.start()
thread1.join()thread2.start()
thread2.join()
7.6 小结
线程(Threading)
- 适合 I/O 密集型任务。
- 受限于 GIL,无法实现真正的并行。
进程(Multiprocessing)
- 适合 CPU 密集型任务。
- 每个进程都有独立的内存空间。
异步编程(Asyncio)
- 适合 I/O 密集型任务。
- 使用
async和await关键字实现。
7.7 实战项目:爬虫示例
使用多线程进行网页爬取
import threading
import requestsdef fetch_url(url):response = requests.get(url)print(f"{url}: {response.status_code}")urls = ["https://www.example.com", "https://www.python.org"]threads = []
for url in urls:t = threading.Thread(target=fetch_url, args=(url,))threads.append(t)t.start()for t in threads:t.join()
相关文章:
Python的秘密基地--[章节7] Python 并发与多线程编程
第7章:Python 并发与多线程编程 随着计算机硬件的发展,多核处理器已经成为主流。为了更好地利用多核资源,提高程序的运行效率,Python 提供了并发(Concurrency)和并行(Parallelism)编…...
每天五分钟机器学习:凸函数
一、凸函数的定义:何为“凸”? 在数学上,凸函数的概念源于几何直观——想象一个平面上的曲线,如果在这条曲线上的任意两点之间连线段总是位于曲线的下方(或恰好与曲线重合),则这条曲线所对应的函数即为凸函数。更正式地,对于定义在实数集(或某个子集)上的函数f(x),…...
Merry Christmas HTML
简单分享 Merry Christmas HTML 设计的核心代码 HTML: <body class"card"> <div class"dialog"><div class"dialog-in"><div class"dialog-msg"><div class"heading">Youve got a post card!…...
JavaScript甘特图 dhtmlx-gantt
背景 需求是在后台中,需要用甘特图去展示管理任务相关视图,并且不用依赖vue,兼容JavaScript原生开发。最终使用dhtmlx-gantt,一个半开源的库,基础功能免费,更多功能付费。 甘特图需求如图: 调…...
阿里云-将旧服务器数据与配置完全迁移至新服务器
文章目录 一:创建镜像二:将创建好的镜像复制到新服务器所在的目标地域(如果新服务器与镜像在同一地域就不用进行这一操作)三:将镜像配置到新服务器上四:导出安全组(如果新服务器与旧服务器使用同…...
以EM算法为例介绍坐标上升(Coordinate Ascent)算法:中英双语
中文版 什么是 Coordinate Ascent 算法? Coordinate Ascent(坐标上升)是一种优化算法,它通过在每次迭代时优化一个变量(或一个坐标),并保持其他变量不变,逐步逼近最优解。与坐标下…...
Spark生态圈
Spark 主要用于替代Hadoop中的 MapReduce 计算模型。存储依然可以使用 HDFS,但是中间结果可以存放在内存中;调度可以使用 Spark 内置的,也可以使用更成熟的调度系统 YARN 等。 Spark有完善的生态圈: Spark Core:实现了…...
CSDN编辑器
这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…...
【信息系统项目管理师】高分论文:论信息系统项目的资源管理(智慧储电站系统)
更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 论文1、规划资源管理2、估算活动资源3、获取资源4、建设团队5、管理团队6、控制资源论文 根据国家2030年前碳达峰行动方案,提出全面推进风电、太阳能发电大规模开发和高质量发展。XX地国家电网启动了“数字李…...
Web开发:ORM框架之使用Freesql的分表分页写法
一、自动分表(高版本可用) 特性写法 //假如是按月分表:[Table(Name "log_{yyyyMM}", AsTable "createtime2022-1-1(1 month)")]注意:①需包含log_202201这张表 ②递增规律是一个月一次,确保他们…...
Unity功能模块一对话系统(1)前置准备
也许你也曾被游戏中的对话系统深深吸引,那些精心设计的对白、鲜活的角色配音、甚至是简单的文字对话,往往能让玩家产生强烈的代入感和情感共鸣。如果你正在开发一款游戏,或者计划为你的项目加入一个引人入胜的对话系统,那么 Unity…...
strrchr的概念和使用案例
strrchr 是 C 语言标准库中的一个函数,用于在字符串中查找最后一次出现的字符,并返回指向该字符的指针。 概念: strrchr 函数在给定的字符串中从末尾开始搜索指定的字符,返回一个指向该字符最后一次出现的指针。如果字符在字符串…...
缓存管理自动化:JuiceFS 企业版 Cache Group Operator 新特性发布
近期,JuiceFS 企业版推出了 Cache Group Operator,用于自动化创建和管理缓存组集群。Operator 是一种简化 Kubernetes 应用管理的工具,它能够自动化应用程序的生命周期管理任务,使部署、扩展和运维更加高效。 在推出 Operator 之前…...
C++ 并发专题 - 实现一个线程安全的队列
一:概述 本文利用 C 标准库中的多线程、条件变量、互斥锁等工具来实现一个线程安全的队列,并且使用多个线程来向队列中添加和获取数据。 二:实现过程: #include <iostream> #include <queue> #include <mutex&g…...
SQL 基础教程
SQL 是用于访问和处理数据库的标准的计算机语言。 在本教程中,您将学到如何使用 SQL 访问和处理数据系统中的数据,这类数据库包括:Oracle, Sybase, SQL Server, DB2, Access 等等。 SQL 是用于访问和处理数据库的标准的计算机语言。 什么是…...
【源码】Sharding-JDBC源码分析之SQL中影子库ShadowSQLRouter路由的原理
Sharding-JDBC系列 1、Sharding-JDBC分库分表的基本使用 2、Sharding-JDBC分库分表之SpringBoot分片策略 3、Sharding-JDBC分库分表之SpringBoot主从配置 4、SpringBoot集成Sharding-JDBC-5.3.0分库分表 5、SpringBoot集成Sharding-JDBC-5.3.0实现按月动态建表分表 6、【…...
雷池 WAF 搭配阿里云 CDN 使用教程
雷池 WAF(Web Application Firewall)是一款强大的网络安全防护产品,通过实时流量分析和精准规则拦截,有效抵御各种网络攻击。在部署雷池 WAF 的同时,结合阿里云 CDN(内容分发网络)可以显著提升网…...
3.银河麒麟V10 离线安装Nginx
1. 下载nginx离线安装包 前往官网下载离线压缩包 2. 下载3个依赖 openssl依赖,前往 官网下载 pcre2依赖下载,前往Git下载 zlib依赖下载,前往Git下载 下载完成后完整的包如下: 如果网速下载不到请使用网盘下载 通过网盘分享的文件…...
【模块一】kubernetes容器编排进阶实战之kubernetes 资源限制
kubernetes 资源限制 kubernetes中资源限制概括 1.如果运行的容器没有定义资源(memory、CPU)等限制,但是在namespace定义了LimitRange限制,那么该容器会继承LimitRange中的 默认限制。 2.如果namespace没有定义LimitRange限制,那么该容器可…...
【开源】一款基于SpringBoot的智慧小区物业管理系统
一、下载项目文件 项目文件源码链接:https://pan.quark.cn/s/3998d958e182如出现网盘空间不够存的情况!!!解决办法是先用夸克手机app注册,然后保存上方链接,就可以得到1TB空间了!!&…...
SenseVoice Small企业级应用:法务合同语音审查+关键条款提取实战
SenseVoice Small企业级应用:法务合同语音审查关键条款提取实战 1. 项目背景与需求场景 在现代企业法务工作中,合同审查是一项频繁且重要的工作。传统的合同审查流程往往需要法务人员逐字阅读大量合同文本,耗时耗力且容易遗漏关键条款。特别…...
CANopen协议学习与实践干货分享
CANopen协议代码,学习资料,包含CANfestival官方代码框架,官方字典生成工具,可自主设定心跳,pdo,sdo等内容参数,并包含已经移植完成的且带有详细注释的一个主站程序两个从站能正常通信࿰…...
2026指纹浏览器与Web端设备识别技术的对抗与协同:从风控博弈到合规共生
在 2026 年的 Web 生态中,指纹浏览器与 Web 端设备识别技术始终处于 “对抗与协同” 的动态平衡中 —— 平台通过设备识别技术构建风控体系,防范恶意注册、批量操作、账号盗用等违规行为;指纹浏览器通过技术手段重构设备特征,实现…...
Hi-C数据分析进阶:如何用dcHiC精准识别癌症样本中的区室转换事件?
Hi-C技术解密:从染色质区室动态到癌症表观遗传调控 染色质三维结构研究已成为癌症表观遗传学的前沿领域。随着Hi-C技术的普及,科学家们能够以前所未有的分辨率观察基因组在细胞核内的空间组织形式。本文将深入探讨染色质区室(A/B compartment…...
Carsim Tiretester保姆级教程:从零生成轮胎特性曲线(附完整Excel数据导入流程)
Carsim Tiretester保姆级教程:从零生成轮胎特性曲线(附完整Excel数据导入流程) 刚接触车辆动力学仿真的工程师或学生,常常会被轮胎特性曲线的生成过程困扰。轮胎作为车辆与地面唯一的接触点,其力学特性直接影响整车的操…...
终极指南:VSCode Rainbow Fart如何通过Vue.js打造沉浸式编程体验
终极指南:VSCode Rainbow Fart如何通过Vue.js打造沉浸式编程体验 【免费下载链接】vscode-rainbow-fart 一个在你编程时疯狂称赞你的 VSCode 扩展插件 | An VSCode extension that keeps giving you compliment while you are coding, it will checks the keywords …...
RAGFlow图片回答避坑指南:为什么不用Base64和阿里云OSS?
RAGFlow图片回答架构设计:从Base64到容器化服务器的技术演进 当RAG系统需要处理包含图片的回答时,技术选型直接关系到系统的性能、安全性和可维护性。本文将深入探讨几种主流方案的优劣对比,并解析为何容器化图片服务器成为当前最优解。 1. 图…...
Java实现Redis延迟队列:从原理到高可用架构
在现代分布式系统中,延迟队列是一种至关重要的组件。它允许我们将消息或任务放入队列,直到指定的延迟时间到达后才被消费。这种机制广泛应用于订单超时自动取消、支付后定时发送通知、任务重试等场景。 虽然RabbitMQ和RocketMQ等专业消息中间件都支持延迟…...
实测避坑:用华为Atlas 300I DUO推理卡跑Qwen1.5-14B,性能对比3090和配置踩坑全记录
华为Atlas 300I DUO推理卡实战评测:Qwen1.5-14B部署全流程与性能深度对比 当国产AI加速卡遇上千亿参数大模型,会碰撞出怎样的火花?最近半年,我陆续测试了市面上主流的7款推理加速设备,这次终于轮到华为Atlas 300I DUO这…...
别再死记硬背!用Python(SymPy库)自动推导DC-DC变换器的小信号模型
用Python解放双手:SymPy自动推导DC-DC变换器小信号模型的工程实践 当电源工程师面对Buck、Boost电路的小信号模型推导时,那些繁琐的矩阵运算和拉普拉斯变换是否让你头疼不已?传统手工推导不仅耗时费力,还容易在代数运算中出错。本…...
