Python入门(13)--并发编程

Python并发编程:从入门到实践 🚀

1. 多线程编程基础 🧵

多线程是实现并发的重要方式,Python提供了threading模块来支持多线程编程。

1.1 基本线程操作

import threading
import time
from typing import List, Callableclass ThreadManager:"""线程管理器:用于创建和管理线程"""def __init__(self):self.threads: List[threading.Thread] = []def create_thread(self, target: Callable, args: tuple = ()) -> threading.Thread:"""创建新线程:param target: 线程执行的目标函数:param args: 传递给目标函数的参数:return: 创建的线程对象"""thread = threading.Thread(target=target, args=args)self.threads.append(thread)return threaddef start_all(self) -> None:"""启动所有线程"""for thread in self.threads:thread.start()def join_all(self) -> None:"""等待所有线程完成"""for thread in self.threads:thread.join()def thread_demo():def worker(name: str, sleep_time: int) -> None:"""线程工作函数"""print(f"线程 {name} 开始工作")time.sleep(sleep_time)print(f"线程 {name} 完成工作")# 创建线程管理器manager = ThreadManager()# 创建多个线程for i in range(3):manager.create_thread(target=worker, args=(f"Thread-{i}", i))# 启动并等待完成manager.start_all()manager.join_all()

1.2 线程同步机制

from threading import Lock, RLock, Condition, Event, Semaphore
from typing import Anyclass ThreadSafe:"""线程安全的资源访问演示"""def __init__(self):self._lock = Lock()self._rlock = RLock()self._condition = Condition()self._event = Event()self._semaphore = Semaphore(2)self._resource = 0def lock_example(self) -> None:"""使用Lock进行互斥访问"""with self._lock:self._resource += 1print(f"资源值: {self._resource}")def rlock_example(self) -> None:"""使用RLock进行可重入锁定"""with self._rlock:with self._rlock:  # 可以重复获取锁self._resource += 1def condition_example(self) -> None:"""使用Condition进行条件同步"""with self._condition:# 等待条件满足self._condition.wait_for(lambda: self._resource > 5)print("条件满足,继续执行")def event_example(self) -> None:"""使用Event进行事件同步"""self._event.wait()  # 等待事件print("事件被触发")def semaphore_example(self) -> None:"""使用Semaphore限制并发访问"""with self._semaphore:print("获得信号量")time.sleep(1)print("释放信号量")## 2. 多进程编程 🔄多进程适合CPU密集型任务,Python的`multiprocessing`模块提供了强大的多进程支持。```python
from multiprocessing import Process, Pool, Queue, Manager
import osclass ProcessManager:"""进程管理器:用于创建和管理进程"""@staticmethoddef process_worker(name: str) -> None:"""进程工作函数:param name: 进程名称"""print(f"进程 {name} (PID: {os.getpid()}) 开始工作")time.sleep(2)print(f"进程 {name} 完成工作")@staticmethoddef pool_example() -> None:"""进程池示例"""with Pool(processes=4) as pool:# 使用进程池并行处理任务results = pool.map(lambda x: x * x, range(10))print(f"进程池计算结果: {results}")@staticmethoddef queue_example() -> None:"""进程间通信示例"""def producer(queue: Queue) -> None:"""生产者进程"""for i in range(5):queue.put(f"item-{i}")time.sleep(1)def consumer(queue: Queue) -> None:"""消费者进程"""while True:item = queue.get()print(f"消费: {item}")# 创建队列和进程q = Queue()p1 = Process(target=producer, args=(q,))p2 = Process(target=consumer, args=(q,))# 启动进程p1.start()p2.start()# 等待生产者完成p1.join()## 3. 异步IO编程 🌊Python的`asyncio`模块提供了异步编程的支持,特别适合IO密集型任务。```python
import asyncio
from typing import List
import aiohttpclass AsyncIOManager:"""异步IO管理器"""@staticmethodasync def async_task(name: str) -> str:"""异步任务示例:param name: 任务名称:return: 任务结果"""print(f"任务 {name} 开始")await asyncio.sleep(1)  # 模拟IO操作print(f"任务 {name} 完成")return f"Result-{name}"async def run_tasks(self) -> List[str]:"""运行多个异步任务:return: 任务结果列表"""tasks = [self.async_task(f"Task-{i}")for i in range(3)]results = await asyncio.gather(*tasks)return results## 4. 实战案例:并发下载器 🚀结合上述所有概念,实现一个高效的并发下载器。```python
import asyncio
import aiohttp
import os
from typing import List, Dict
from dataclasses import dataclass
from concurrent.futures import ThreadPoolExecutor
import threading@dataclass
class DownloadTask:"""下载任务数据类"""url: strfilename: strsize: int = 0downloaded: int = 0status: str = 'pending'class ConcurrentDownloader:"""并发下载器支持多线程、多进程和异步IO"""def __init__(self, save_dir: str = './downloads'):self.save_dir = save_dirself.tasks: Dict[str, DownloadTask] = {}self.lock = threading.Lock()os.makedirs(save_dir, exist_ok=True)async def async_download(self, url: str, filename: str) -> None:"""异步下载单个文件:param url: 下载URL:param filename: 保存的文件名"""task = DownloadTask(url=url, filename=filename)self.tasks[url] = tasktry:async with aiohttp.ClientSession() as session:async with session.get(url) as response:if response.status == 200:task.size = int(response.headers.get('content-length', 0))filepath = os.path.join(self.save_dir, filename)with open(filepath, 'wb') as f:while True:chunk = await response.content.read(8192)if not chunk:breakf.write(chunk)task.downloaded += len(chunk)task.status = 'completed'else:task.status = 'failed'except Exception as e:print(f"下载错误 {url}: {str(e)}")task.status = 'failed'async def batch_download(self, urls: List[Dict[str, str]]) -> None:"""批量下载文件:param urls: URL和文件名的字典列表"""tasks = [self.async_download(item['url'], item['filename'])for item in urls]await asyncio.gather(*tasks)def get_progress(self) -> Dict[str, Dict]:"""获取下载进度:return: 所有任务的进度信息"""with self.lock:return {url: {'filename': task.filename,'size': task.size,'downloaded': task.downloaded,'status': task.status,'progress': (task.downloaded / task.size * 100) if task.size > 0 else 0}for url, task in self.tasks.items()}# 使用示例
async def download_demo():"""下载器示例"""downloader = ConcurrentDownloader()# 准备下载任务urls = [{'url': 'http://example.com/file1.zip', 'filename': 'file1.zip'},{'url': 'http://example.com/file2.pdf', 'filename': 'file2.pdf'},]# 开始下载await downloader.batch_download(urls)# 获取进度progress = downloader.get_progress()print("下载进度:", progress)if __name__ == "__main__":# 运行异步下载示例asyncio.run(download_demo())

5. 最佳实践与注意事项 ⚠️

  1. 线程使用建议:

    • GIL限制了Python多线程在CPU密集型任务上的表现
    • 适合IO密集型任务
    • 注意线程安全和死锁问题
  2. 进程使用建议:

    • 适合CPU密集型任务
    • 注意进程间通信的开销
    • 合理使用进程池
  3. 异步IO使用建议:

    • 适合大量IO操作场景
    • 避免在协程中使用阻塞操作
    • 使用异步库而不是同步库
  4. 性能优化:

    • 根据任务特点选择合适的并发方式
    • 避免过度并发
    • 合理设置超时和重试机制

6. 拓展学习方向 🎯

  1. 深入研究Python的GIL机制
  2. 探索分布式计算框架
  3. 学习反应式编程
  4. 研究并发设计模式
  5. 了解更多异步框架(如Trio)

通过本文的学习,你已经掌握了Python并发编程的核心概念和实践技巧。继续探索和实践,你将能够构建更高效的并发应用!🐍✨


如果你觉得这篇文章有帮助,欢迎点赞转发,也期待在评论区看到你的想法和建议!👇

咱们下一期见!

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

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

相关文章

SpringCloud Gateway转发请求到同一个服务的不同端口

SpringCloud Gateway默认不支持将请求路由到一个服务的多个端口 本文将结合Gateway的处理流程,提供一些解决思路 需求背景 公司有一个IM项目,对外暴露了两个端口8081和8082,8081是springboot启动使用的端口,对外提供一些http接口…

Parker派克防爆电机在实际应用中的安全性能如何保证?

Parker防爆电机确保在实际应用中的安全性能主要通过以下几个方面来保证: 1.防爆外壳设计:EX系列电机采用强大的防爆外壳,设计遵循严格的防爆标准,能够承受内部可能发生的爆炸而不破损,利用间隙切断原理,防…

虚拟形象+动作捕捉:解锁品牌N种营销玩法

近年来,随着Z世代年轻人对于二次元文化的热爱,各种二次元内容频频出圈。为了吸引年轻观众的注意,虚拟IP形象成为了品牌营销的“新宠”与“利器”为品牌踏入元宇宙蓝海提供了关键的切入点。在此背景下虚拟形象动作捕捉技术的组合应用方式正成为…

空间计算、物理计算、实时仿真与创造拥有「自主行为」的小狗 | 播客《编码人声》

「编码人声」是由「RTE开发者社区」策划的一档播客节目,关注行业发展变革、开发者职涯发展、技术突破以及创业创新,由开发者来分享开发者眼中的工作与生活。 虚拟世界与现实世界的界限逐渐模糊,已然成为不争的事实。但究竟哪些曾经的幻想已然…

影响电阻可靠性的因素

一、影响电阻可靠性的因素: 影响电阻可靠性的因素有温度系数、额定功率,最大工作电压、固有噪声和电压系数 (一)温度系数 电阻的温度系数表示当温度改变1摄氏度时,电阻阻值的相对变化,单位为ppm/C.电阻温度…

JAVA后端如何调用百度的身份证识别API

大家好,我是 程序员码递夫 。 今天给大家分享的是 JAVA后台如何调用百度的身份证识别API。 1、前言 我们做APP开发时常遇到 身份证认证或资质认证的 需求, 通过上传身份证照片是个常用的操作, 后台对上传的身份证照信息进行识别&#xff0…

Go语言进阶依赖管理

1. Go语言进阶 1.1 Goroutine package mainimport ("fmt""time" )func hello(i int) {println("hello goroutine : " fmt.Sprint(i)) }func main() {for i : 0; i < 5; i {go func(j int) { hello(j) }(i) // 启动一个新的 goroutine&…

基于Java Springboot高考志愿填报辅助系统

一、作品包含 源码数据库全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据库&#xff1a;…

autoware(2)运行自己的数据集

上一节完成了autoware.ai的安装和编译跑通了demo数据集&#xff0c;本将自己录制的数据包用于测试 1.修改点云地图 将加载点云地图的my_map.launch文件复制并命名为my_map_test.launch&#xff0c; &#xff08;1&#xff09;point cloud处替代原来的点云地图为自己的&#…

el-select 和el-tree二次封装

前言 本文章是本人在开发过程中&#xff0c;遇到使用树形数据&#xff0c;动态单选或多选的需求&#xff0c;element中没有这种组件&#xff0c;故自己封装一个&#xff0c;欢迎多多指教 开发环境&#xff1a;element-UI、vue2 组件效果 单选 多选 组件引用 <treeselec…

【LeetCode热题100】栈

这道题一共记录了关于栈的5道题目&#xff1a;删除字符串中所有相邻重复项、比较含退格的字符串、基本计算器II、字符串解码、验证栈序列。 class Solution { public:string removeDuplicates(string s) {string ret;for(auto c : s){if(ret.size() 0 || c ! ret.back()) ret …

《Python基础》之pip换国内镜像源

目录 推荐镜像源网址&#xff1a; 方法一&#xff1a;手动换源 方法二&#xff1a;命令提示符指令换源 临时换源 推荐镜像源网址&#xff1a; 阿里云&#xff1a;Simple Indexhttp://mirrors.aliyun.com/pypi/simple/ 华为云&#xff1a;Index of python-local https://m…

全面击破工程级复杂缓存难题

目录 一、走进业务中的缓存 &#xff08;一&#xff09;本地缓存 &#xff08;二&#xff09;分布式缓存 二、缓存更新模式分析 &#xff08;一&#xff09;Cache Aside Pattern&#xff08;旁路缓存模式&#xff09; 读操作流程 写操作流程 流程问题思考 问题1&#…

Kafka 分区分配及再平衡策略深度解析与消费者事务和数据积压的简单介绍

Kafka&#xff1a;分布式消息系统的核心原理与安装部署-CSDN博客 自定义 Kafka 脚本 kf-use.sh 的解析与功能与应用示例-CSDN博客 Kafka 生产者全面解析&#xff1a;从基础原理到高级实践-CSDN博客 Kafka 生产者优化与数据处理经验-CSDN博客 Kafka 工作流程解析&#xff1a…

[Unity Demo]从零开始制作空洞骑士Hollow Knight第二十集:制作专门渲染HUD的相机HUD Camera和画布HUD Canvas

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、制作HUD Camera以及让两个相机同时渲染屏幕二、制作HUD Canvas 1.制作法力条Soul Orb引入库2.制作生命条Health读入数据3.制作吉欧统计数Geo Counter4.制作…

30. 并发编程

一、什么是多任务 如果一个操作系统上同时运行了多个程序&#xff0c;那么称这个操作系统就是 多任务的操作系统&#xff0c;例如&#xff1a;Windows、Mac、Android、IOS、Harmony 等。如果是一个程序&#xff0c;它可以同时执行多个事情&#xff0c;那么就称为 多任务的程序。…

ElasticSearch学习篇17_《检索技术核心20讲》最邻近检索-局部敏感哈希、乘积量化PQ思路

目录 场景在搜索引擎和推荐引擎中&#xff0c;对相似文章去重是一个非常重要的环节&#xff0c;另外是拍照识花、摇一摇搜歌等场景都可以使用它快速检索。 基于敏感性哈希的检索更擅长处理字面上的相似而不是语义上的相似。 向量空间模型ANN检索加速思路 局部敏感哈希编码 随…

mongodb多表查询,五个表查询

需求是这样的&#xff0c;而数据是从mysql导入进来的&#xff0c;由于mysql不支持数组类型的数据&#xff0c;所以有很多关联表。药剂里找药物&#xff0c;需要药剂与药物的关联表&#xff0c;然后再找药物表。从药物表里再找药物与成分关联表&#xff0c;最后再找成分表。 这里…

《机器人控制器设计与编程》考试试卷**********大学2024~2025学年第(1)学期

消除误解&#xff0c;课程资料逐步公开。 复习资料&#xff1a; Arduino-ESP32机器人控制器设计练习题汇总_arduino编程语言 题-CSDN博客 试卷样卷&#xff1a; 开卷考试&#xff0c;时间&#xff1a; 2024年11月16日 001 002 003 004 005 ……………………装………………………

DataWorks快速入门

DataWorks基于MaxCompute、Hologres、EMR、AnalyticDB、CDP等大数据引擎&#xff0c;为数据仓库、数据湖、湖仓一体等解决方案提供统一的全链路大数据开发治理平台。本文以DataWorks的部分核心功能为例&#xff0c;指导您使用DataWorks接入数据并进行业务处理、周期调度以及数据…