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

Python线程与锁:为何将计算移出锁区域能提升代码运行速度?

为什么Python线程池版本B比版本A快这么多?

这问题问得非常到位,核心原因和GIL的释放规则以及hashlib.sha256的底层实现直接相关,咱们一步步拆解清楚:

1. 版本A的核心瓶颈:锁强制了完全串行

版本A把哈希计算和字典更新整个包裹在with lock:块里,这意味着同一时间只能有一个线程执行这段代码——不管GIL的规则是什么,锁本身就把所有任务变成了串行执行。1000个任务必须一个接一个地完成哈希计算和写入操作,速度自然慢得离谱。

2. 版本B的提速关键:C扩展会临时释放GIL

Python的GIL确实会限制线程并行执行Python字节码,但有个关键例外:当执行线程安全的C扩展耗时操作时,解释器会临时释放GIL。

hashlib.sha256的底层是基于OpenSSL的C代码实现,属于线程安全的CPU密集型扩展。当你的线程调用hashlib.sha256(...).hexdigest()时,Python解释器会:

  • 主动释放GIL,允许其他线程执行代码
  • 调用底层C代码完成sha256哈希计算
  • 计算完成后重新获取GIL,继续执行后续Python代码

在版本B中,哈希计算是在锁外面的,所以多个线程可以同时进入sha256的C计算阶段,实现真正的并行计算。只有最后更新字典的那一小段Python字节码操作需要加锁,这部分耗时极短,几乎不影响整体性能。

3. 额外补充:生成字符串的影响

你代码里的s = '*'*(x + 100000)和f'{s}'.encode()是纯Python字节码操作,这时候GIL是持有的,无法并行。但这些操作的耗时远低于sha256计算,所以即使这部分串行,整体性能依然被哈希计算的并行效果拉起来了,最终版本B的速度远快于A。

再对比两个版本的执行流程

  • 版本A:线程1获取锁 → 计算哈希 → 写入字典 → 释放锁 → 线程2获取锁 → 重复...(完全串行执行所有操作)
  • 版本B:线程1计算哈希(释放GIL,线程2同时计算哈希)→ 线程1获取锁写入字典 → 释放锁;线程2计算完成后获取锁写入字典 → 释放锁...(计算阶段并行,写入阶段串行但耗时极短)

测试结果里B比A快3-4倍,正好符合线程池在C扩展并行下的性能提升逻辑(实际提升幅度受CPU核心数限制,但肯定远大于串行执行)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 20:17:53