You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python多线程中CPU Time大于Wall Time的原因探究

疑问:Python多线程下CPU总时间为何超过墙钟时间?

我编写了一段单进程多线程的Python代码,通过计时器运行:

import random
import threading
import hashlib

a = "".join([chr(ord('a') + random.randint(1, 20)) for _ in range(50_000_000)])

def sum_part(i):
    part = a[i * 20_000_000: (i+1) * 20_000_000]
    size = 1_000_000
    splits = [part[j: j + size] for j in range(0, len(part), size)]
    hashes = [hashlib.sha1(bytes(k, "utf-8")).hexdigest() for k in splits]
    return "".join(hashes)

def calc_split():
    threads = [threading.Thread(target=sum_part, args=[i]) for i in range(2)]
    for t in threads:
        t.start()
    for t in threads:
        t.join()

得到如下计时结果:

CPU times: user 118 ms, sys: 36.7 ms, total: 155 ms
Wall time: 110 ms

按我的理解,Python的GIL应该限制同一时间只有一个CPU线程执行Python字节码,但这里CPU总时间(155ms)却超过了墙钟时间(110ms)——这种情况在C++多线程里很正常,但GIL的存在不该让Python出现这种情况吧?我忽略了什么?


核心原因:GIL在执行C扩展代码时会主动释放

你看到的CPU总时间超过墙钟时间,本质是因为代码中的hashlib.sha1()属于C实现的扩展模块:这类底层耗时操作执行时,Python会自动释放GIL,允许其他线程同时占用CPU资源。

具体细节:

  • 当线程进入hashlib.sha1()的计算逻辑时,GIL被释放,另一个线程可以立刻启动自己的哈希计算,两个线程的CPU时间会并行累积,最终总和超过实际流逝的墙钟时间。
  • 你代码里的字符串切片、列表推导等纯Python字节码操作,确实受GIL限制只能单线程执行,但这些操作的耗时占比极低,对整体计时结果影响很小。
  • 系统时间(sys:36.7ms)主要来自字符串转字节、内存拷贝等系统调用,这类操作同样会让线程暂时释放GIL,进一步增加总CPU时间的累积。

简言之:GIL只限制Python字节码的并行执行,对于底层用C实现的耗时操作,Python会放开GIL允许真正的多CPU并行,这就是你看到CPU总时间超过墙钟时间的关键原因。


内容的提问来源于stack exchange,提问作者sygi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 20:40:30