Python并发编程学习 day1
2025-06-12 15:57 第二个卿老师 阅读(34) 评论(0) 收藏 举报Day 1:Python 并发编程基础
一、并发 vs 并行
- 并发(Concurrency):代表多个任务、线程、进程在“同一时段”处理,从低层级看,在抢占式多任务处理系统中,处理器上多个操作指令会快速的轮流切换,看似同时处理
- 并行(Parallelism):代表多个任务、线程、进程在同时处理,这里的同时是真正意义上的同时,主要体现在多核处理器上
并发指多个任务能够以重叠的方式运行,并行是指同时执行多个操作,可以说并发包含了并行
举例说明:
- 并发示例:多个线程在1s内并发处理了100个网络请求
- 并行示例:多个进程在多核处理器上并行计算数学公式
二、同步 vs 异步
- 同步(Synchronous):工作流有多个操作时,上一个操作完成后需要等待响应结束,才进行下一个操作
- 异步(Asynchronous):工作流有多个操作时,上一个操作完成后,在等待响应的时间间隔中,主动切换到下一个操作
三、线程 / 进程 / 协程 概念对比
| 对比维度 | 线程 (Thread) | 进程 (Process) | 协程 (Coroutine) |
|---|---|---|---|
| 是否并发 | ✅ | ✅ | ✅ |
| 内存隔离 | 共享内存 | 独立内存 | 共享上下文(单线程) |
| 开销 | 较小 | 较大 | 最小 |
| 启动速度 | 快 | 慢 | 非常快 |
| 切换方式 | 操作系统调度(上下文切换) | 操作系统调度 | 协作式用户态调度 |
| 最佳场景 | I/O密集型 | CPU密集型 | I/O密集且需高并发 |
在计算机系统结构中,开发并行性的途径有时间重叠、资源重复和资源共享等方式,可以简单理解线程模型是时间重叠、进程模型是资源重复、协程(异步IO)是资源共享
四、Python 中的并发机制
threading:作为Python进程创建的多个线程进行任务处理,也属于操作系统线程,由操作系统决定何时调度,由于GIL原因,单进程不支持多核并行处理,multiprocessing:属于操作系统原生进程,由主进程创建多个子进程进行任务处理,也由操作系统调度,支持多核并行处理asyncio:属于Python进程中的单个线程,无需操作系统调度,通过事件循环控制每个异步任务的执行方式和时间
五、GIL 的本质
- 什么是 GIL?:
答:即Python 全局解释器锁,它是一个互斥锁(或锁),它只允许一个线程控制 Python 解释器,可以带来单线程的性能提升并防止死锁 - 对 Python 多线程的影响:
答:在任何时间点都只能有一个线程处于执行状态,即使在具有多个 CPU 核心的多线程架构,即在编写 C 扩展或在程序中使用 CPU 密集型多线程时会受到影响。 - 对多进程或协程的影响:
答:多进程中每个进程都有自己的python解释器,协程本质也是一个线程进行事务处理,所以都不会有影响
🔁 今日思考题
- 为什么 Python 的多线程不能提升 CPU 密集型任务的性能?
答:因为CPU密集型主要是CPU的计算,在任何时间点都只能有一个线程处于执行状态,浪费了多核处理器的资源,而IO密集型主要是IO操作,由于线程在等待 I/O 时,锁是在线程之间共享的,所以没有太大影响 - 协程比线程更轻量,它是如何做到的?
答:协程是在单个线程内部实现并发的一种机制,在用户态实现,它们运行在一个或多个操作系统线程之上,程序可以创建大量协程,而不会产生显著的内存或性能开销,通过使用事件循环、非阻塞操作等异步IO机制,避免了线程间上下文切换的开销 - 如果要处理 1 万个网络请求任务,你会选择哪种并发方式?为什么?
答:1万个网络请求任务即是IO密集型任务,如果没有同步任务,则采用多进程+全协程的方式,如果存在同步任务,则采用多进程+多线程+协程方式。因为执行同步任务会阻塞事件循环,该线程会等待IO,这时如果是多线程,把同步任务或阻塞操作放到另外的线程中,那么该线程等待IO时会释放GIL锁,可由协程所在线程继续执行
浙公网安备 33010602011771号