用同一个CPU密集任务对比单线程、2线程、2进程三种跑法的耗时,验证GIL是怎么锁住线程并行、又是怎么锁不住多进程的。
一个纯计算函数(循环3000万次累加平方),分别用单线程串行、2线程并发、2进程并发跑两遍。
代码def cpu_bound(n): x = 0 for i in range(n): x += i * i return x N = 30_000_000 # 单线程串行跑2遍 / 2个threading.Thread并发跑 / 2个multiprocessing.Process并发跑
本机10核CPU,理论上2个线程应该能提速接近2倍。
结果单线程串行跑2遍: 耗时 2.3180s 2个线程并发跑(threading): 耗时 2.3669s ← 跟单线程几乎一样,甚至略慢! 2个进程并发跑(multiprocessing): 耗时 1.1651s ← 提速约2倍 本机CPU核心数: 10
结果很直接:2个线程"并发"执行CPU密集计算,耗时(2.3669s)跟单线程串行(2.3180s)几乎一样,完全没有利用上多核——这就是GIL(全局解释器锁)的效果:同一时刻,只允许一个线程执行Python字节码,哪怕你开了10个线程、本机有10个核心,纯计算型代码也只能有一个线程在跑,其它线程都在等这把锁。
换成2个独立的进程,耗时降到1.1651s,接近理论上的2倍提速——因为每个进程都有自己独立的Python解释器和GIL,互不干扰,能同时用上2个CPU核心。
每一步都是本文上面在10核CPU上跑出来的原始耗时。
threading.Thread vs multiprocessing.Process:对比CPU密集任务的加速效果