代码改变世界

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解释器,协程本质也是一个线程进行事务处理,所以都不会有影响

🔁 今日思考题

  1. 为什么 Python 的多线程不能提升 CPU 密集型任务的性能?
    答:因为CPU密集型主要是CPU的计算,在任何时间点都只能有一个线程处于执行状态,浪费了多核处理器的资源,而IO密集型主要是IO操作,由于线程在等待 I/O 时,锁是在线程之间共享的,所以没有太大影响
  2. 协程比线程更轻量,它是如何做到的?
    答:协程是在单个线程内部实现并发的一种机制,在用户态实现,它们运行在一个或多个操作系统线程之上,程序可以创建大量协程,而不会产生显著的内存或性能开销,通过使用事件循环、非阻塞操作等异步IO机制,避免了线程间上下文切换的开销
  3. 如果要处理 1 万个网络请求任务,你会选择哪种并发方式?为什么?
    答:1万个网络请求任务即是IO密集型任务,如果没有同步任务,则采用多进程+全协程的方式,如果存在同步任务,则采用多进程+多线程+协程方式。因为执行同步任务会阻塞事件循环,该线程会等待IO,这时如果是多线程,把同步任务或阻塞操作放到另外的线程中,那么该线程等待IO时会释放GIL锁,可由协程所在线程继续执行