python多线程代码运行速度更慢-原因解析

写出了正确的多线程代码,运行速度反而比单线程慢很多,原来是由于GIL(Global Interpreter Lock)!
GIL 是Cpython(Python语言的主流解释器)特有的全局解释器锁(其他解释器因为有自己的线程调度机制,所以没有GIL机制),GIL锁定Python线程中的CPU执行资源。线程在执行代码时,必须先获得这把锁,才获得CPU执行代码指令。如果这把锁被其他线程占用,该线程就只能等待,等到占有该锁的线程释放锁。
在Cpython解释器中,线程要想执行CPU指令需要2个条件:

  1. 被操作系统调度出来(操作系统允许它占用CPU)
  2. 获取到GIL(Cpython解释器允许它执行指令)

如果写出正确的多线程代码,执行的情况就是会有线程满足条件1不满足条件2,这时只能等待。
在单核CPU机器上,多线程与单线程在本质上并无不同,因为所有线程都是轮流占用CPU。多个线程慢于一个线程,因为其他线程还要先调度出来,再等待。
在多核CPU机器上,多线程代码运行性能会非常糟糕,比单核更糟糕。因为这时候多一个步骤,不同的CPU再竞争GIL,GIL只有一个。Python在多核CPU上的多核CPU也只有单线程在跑程序。

可以有哪些解决办法呢?【绕开GIL的影响】

  1. 使用多进程(多进程之间没有GIL限制)
  2. 使用Jython, IronPython等无GIL的解释器
  3. 使用协程(高效的单线程模式)

GIL的设置有其优点和可取之处,在Cpython解释器框架之下难以绕过这一限制。可以用PyPy解释器,麻烦之处在于很多第三方库在PyPy下无法使用,或者重新安装第三方库的PyPy版本。运行时候,PyPy **.py即可。Cpython下是Python **.py。
I/O的多线程还是快于单线程,因为优先级在获取GIL之上,I/O并行运算的时候,GIL处于release状态。

你可能感兴趣的:(python多线程代码运行速度更慢-原因解析)