众所周知,python这门语言在单个脚本运行的时候只能利用单个核心,但是python本身又有threading这个库来实现所谓的多线程。那么Python的多线程到底是个什么玩意呢=_=
简单写一个验证程序
import threading
def loop():
i=0
while 1:
i=i+1
threading.Thread(target=loop).start()
threading.Thread(target=loop).start()
我们期望的结果是在一个多核心cpu的系统上,有两个核心被占满。那么实际跑一下看看结果
可以发现确实跑在了两个核心上,但是wait…怎么一个核心只有50%的占用率,这python的多线程未免有些抽象了。经过查阅资料$^1$之后,发现了Python中存在的一个祖传史山GIL,翻译过来就是全局变量锁。
抽象就抽象在,同一时刻只能有一个线程获取我们的GIL锁,当这个线程拿到锁之后,才可以读取并执行只属于ta的字节码,时间片一过或遇到IO等待$^2$,这个锁就又要交还给其它的线程使用,这就导致同一时刻只有一个线程可以处于活动状态。其实这和协程也就没什么区别了。
总结一下,高并发,低IO调用的程序不要用python写,如果一定要用的话,那么就开多进程,使用进程间的通信来实现。虽然python中的线程确实是标准的posix实现,但是由于拉跨的GIL,实际的效果还不如开协程来实现逻辑。
参考资料:
- [1] 廖雪峰的官方网站
2023/7/10附:似乎GIL将可以在之后的新版的Python中关闭。可喜可贺