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)