Python2与Python3多线程CPU占用率差异原因咨询
Python 2与Python 3双死循环线程CPU占用差异原因
CPython的GIL(全局解释器锁)确实会限制纯Python代码的多线程并行能力,但Python 2和Python 3的GIL实现逻辑存在本质区别,这就是测试结果出现差异的核心原因:
两种GIL调度机制的核心区别
- Python 2.7采用基于字节码计数的抢占式GIL调度:默认每执行100条Python字节码(对应
sys.getcheckinterval()的默认返回值100),当前持锁线程就会被迫释放GIL,供其他等待线程竞争。这个实现有个广为人知的缺陷:在多核心CPU上,会频繁出现GIL颠簸现象——刚释放GIL的线程往往会在当前运行的核心立刻重新抢到锁,其他核心上等待GIL的线程会持续自旋空转等锁。操作系统统计CPU占用时,会把这部分无意义的自旋等待时间算入CPU消耗,因此在2核机器上会看到接近200%的占用,但实际上同一时间只有一个线程在真正执行Python代码,多出来的CPU消耗全是锁竞争带来的无效开销,实际计算效率甚至比单线程还低。 - Python 3.2及之后版本(包括测试用的3.8.1)完全重写了GIL实现,换成固定时间片调度+优化的锁唤醒机制:默认GIL持有时间片为5毫秒(可通过
sys.getswitchinterval()查询配置),同时新增了等待线程的休眠唤醒逻辑,彻底避免了多核心下的无意义自旋——等锁的线程不会占着CPU空转,只有当前持锁线程主动释放锁、或者时间片到期时才会被唤醒参与竞争。因此在纯CPU密集的双死循环测试场景里,同一时间只会用满1个CPU核心,总占用稳定在100%左右,不会产生额外的空转消耗。
测试场景补充说明
测试用的while 1: pass是最典型的无IO纯CPU密集场景:
- Python 2.7下看到的近200%CPU占用不是真正的多核心并行,只是锁竞争带来的无效消耗,代码实际运行速度并不会比单线程更快。
- 不管是Python2还是Python3,CPU密集型任务都无法靠多线程利用多核心,要跑满多核必须用
multiprocessing多进程模块绕开GIL限制。
内容的提问来源于stack exchange,提问作者Joey.Chang
相关产品推荐
相关产品推荐

