情景描述
最近在做实验时,想到用多线程来加快对数据集的加载速度。在尝试后总感觉时间依旧很慢,于是查阅资料得知:python多线程是个天坑!
Python中的多线程是假的多线程! 因为Cpython解释器有一个东西叫全局解释器锁(GIL)。在解释器解释执行 Python 代码时,先要得到这把锁,意味着,任何时候只可能有一个线程在执行代码,其它线程要想获得 CPU 执行代码指令,就必须先获得这把锁,如果锁被其它线程占用了,那么该线程就只能等待,直到占有该锁的线程释放锁才有执行代码指令的可能。所以python多线程实际上等价于单线程,而且还在切换线程上浪费很多时间!
测试
运行下面的函数testadd()
10次,分别使用单线程、多线程、多进程
import time
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
def testadd():
s = 0
for i in range(int(1e7)):
s += i
s /= 2
return s
if __name__ == '__main__':
time1 = time.perf_counter()
for i in range(10):
testadd()
time2 = time.perf_counter()
print(f'{time2 - time1:.2f}')
pool = ThreadPoolExecutor(max_workers=8)
tasks = [pool.submit(testadd) for i in range(10)]
for t in tasks:
t.result()
time3 = time.perf_counter()
print(f'{time3 - time2:.2f}')
pool = ProcessPoolExecutor(max_workers=8)
tasks = [pool.submit(testadd) for i in range(10)]
for t in tasks:
t.result()
time4 = time.perf_counter()
print(f'{time4 - time3:.2f}')
运行结果:
6.33
17.38
1.06
可以看出,当单线程耗时6秒时,多线程耗时17秒!几乎3倍的时间!而多进程时间仅为1秒!