Python中threading多线程为何无法提升计算任务执行速度?
问题根因
你观察到的多线程耗时高于串行的现象,是CPython解释器的全局解释器锁(GIL) 机制导致的,属于Python多线程的核心特性,不是线程调用逻辑写错了。
关键概念说明
- GIL的核心规则:日常安装使用的官方CPython解释器中存在一把全局互斥锁,同一进程内同一时刻永远只有一个线程能执行Python字节码。哪怕设备是多核CPU,Python多线程也无法在CPU密集型场景下实现真正的并行执行。
- 你的测试任务属性:你写的
task函数是两层嵌套循环做数值计算,属于典型的CPU密集型任务——整个执行过程全程占用CPU做运算,不会主动释放GIL。多线程运行时,多个线程会频繁争抢GIL所有权,线程上下文切换、锁争抢都会产生额外的性能开销,这类额外开销在纯计算场景下占比很高,最终总耗时必然比全程无切换、一直持有GIL运行的串行执行更高。 - Python多线程的适用场景:只有IO密集型任务(比如读写磁盘、发送网络请求、调用
sleep()等待)用多线程才会提速,这类任务在等待IO响应时会主动释放GIL,允许其他线程趁这个间隙执行,避免CPU空等。
CPU密集型任务的并行方案
如果要给这类纯计算的CPU密集型任务做并行加速,不要用threading模块,改用multiprocessing多进程模块即可:多进程模式下每个进程都有独立的解释器实例和独立的GIL,能真正调用多核CPU实现并行计算,不会受GIL限制。
你的测试代码如下:
from time import sleep, perf_counter from threading import Thread def task(id): print(f'Starting the task {id}...') for i in range(1, 1000): for j in range(1, 1000): b=(i**2)/(i*j**3) print(f'The task {id} completed') ############## sequential ############## start_time = perf_counter() for n in range(1, 11): task(n) end_time = perf_counter() print(f'sequential took {end_time- start_time: f} second(s) to complete.') ##########E Multi-threading ########## start_time = perf_counter() threads = [] for n in range(1, 11): t = Thread(target=task, args=(n,)) threads.append(t) t.start() for t in threads: t.join() end_time = perf_counter() print(f'multi-threaded took {end_time- start_time: f} second(s) to complete.')
验证提示:你可以把task里的两层循环换成
sleep(1)模拟IO等待,再跑一次对比,就会发现多线程版本耗时只需要1秒多,远低于串行版本的10秒多,这就是Python多线程真正能发挥作用的场景。
内容的提问来源于stack exchange,提问作者b3hn4m
相关产品推荐
相关产品推荐

