GIL 是 Python(CPython 实现)中的一个机制:
同一时间只有一个线程能执行 Python 字节码,即便你有多个线程
原因:CPython 为了简化内存管理(引用计数),引入了 GIL 保证线程安全。
Python 的 GIL(全局解释器锁)限制了 同一时刻只能一个线程执行 Python 字节码。
所以你即使启动 10 个线程并行执行 CPU 密集任务,它们会轮流获取 GIL,一个一个执行,看起来像是串行。
import threading
def cpu_heavy():
count = 0
for i in range(10**8):
count += i
print("done")
# 启动 4 个线程
for _ in range(4):
threading.Thread(target=cpu_heavy).start()
你可能以为会利用多核加速,其实不会:
由于 GIL,4 个线程是串行运行的,CPU 核心使用率可能只到 100%,而不是 400%。
你会发现总耗时几乎 ≈ 单线程 × 4,这就是 GIL 的影响。
哪些操作会“释放 GIL”?
I/O 操作:如文件读写、网络请求 → 会释放 GIL → 多线程能并发
一些 C 扩展库(NumPy、Pillow)内部会释放 GIL → 并发性能好
纯 Python 的 CPU 密集计算不会释放 GIL
def io_task():
time.sleep(2) # 这是 I/O,释放 GIL
import time
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
# 模拟 CPU 密集任务:递归计算斐波那契数(慢且消耗 CPU)
def cpu_bound_task(n: int) -> int:
if n <= 1:
return n
return cpu_bound_task(n - 1) + cpu_bound_task(n - 2)
N = 35 # 越大越耗 CPU,建议 35 左右做测试
TASKS = 4 # 启动 4 个并发任务
def run_with_executor(name: str, executor_class):
print(f"\nRunning with {name}")
start = time.time()
with executor_class() as executor:
futures = [executor.submit(cpu_bound_task, N) for _ in range(TASKS)]
results = [f.result() for f in futures]
end = time.time()
print(f"{name} finished in {end - start:.2f} seconds")
return results
if __name__ == "__main__":
run_with_executor("ThreadPoolExecutor", ThreadPoolExecutor)
run_with_executor("ProcessPoolExecutor", ProcessPoolExecutor)