🐍 Python 多线程执行原理
基于 CPython 解释器的线程机制解析
🖥️ 进程结构
📦
Python 进程
Process
🔧
CPython 解释器
Python.exe
🧵
线程调度器
OS Scheduler
🧵 线程创建
⭐
Thread-1
Main Thread
🔹
Thread-2
Worker
🔹
Thread-3
Worker
🔹
Thread-N
...
🔒 GIL
Global Interpreter Lock
全局解释器锁 — Python 最核心的并发机制
同一时刻只允许一个线程执行 Python 字节码
⚡ 执行流程
1
🎯 线程启动
用户代码创建 Thread 对象,调用 start() 方法,线程进入就绪状态
2
📋 OS 调度
操作系统决定哪个线程获得 CPU 时间片,线程进入运行状态
3
🔒 获取 GIL
线程尝试获取 GIL 锁,只有持有 GIL 的线程才能执行 Python 字节码
4
💻 执行字节码
在线程内部,Python 虚拟机执行字节码指令序列
5
⏰ GIL 释放
每执行一定数量字节码或遇到 I/O 操作时,GIL 被释放
6
🔄 循环切换
其他等待中的线程获得 GIL,继续执行,形成"伪并发"
⚠️
CPU 密集型瓶颈
由于 GIL 限制,多线程对 CPU 密集型任务几乎没有加速效果,反而因为线程切换开销而变慢
✅
I/O 密集型优势
对于网络请求、文件读写等 I/O 等待操作,线程可在等待期间释放 GIL,让其他线程工作
🔄
线程切换机制
每 100 个字节码指令(可配置),Python 会自动切换线程,也可在 I/O 操作时切换
🛡️
线程安全保证
GIL 天然保证了 Python 对象引用的线程安全性,但需注意用户自定义的锁和共享资源
💡 代码示例:线程创建与 GIL 交互
import
threading
# 1. 创建线程
thread1
= threading.Thread(target=
worker
, args=(
"A"
,))
thread2
= threading.Thread(target=
worker
, args=(
"B"
,))
# 2. 启动线程
thread1
.
start
()
thread2
.
start
()
# 3. GIL 保证同一时刻只有一个线程执行 Python 代码
# 线程在 I/O 等待时会释放 GIL,其他线程才有机会执行
def
worker
(name):
for
i
in
range
(
5
):
# 执行时持有 GIL
print
(
f"Thread {name}: {i}"
)
# I/O 操作会触发 GIL 释放