Python GIL全局解释器锁

独自空忆成欢 提交于 2019-12-02 05:38:10

GIL解释:

GIL:Global Interpreter Lock 全局解释器锁,设计目的是保证数据安全。

GIL 的功能是:在 CPython 解释器中执行的每一个 Python 线程,都会先锁住自己,以阻止别的线程执行。也就是说在解释器执行任何Python代码时,都需要先获取这把锁,意味着任何时候只可能有一个线程在执行代码,其他线程要想获得CPU去执行代码,就必须等到占有该锁的线程释放锁才有执行的可能。

当然Python中不会让一个线程一直独占解释器,它会轮流执行 Python 线程,即 Python 线程在交替执行,来模拟真正并行的线程(伪并行),但Python中每次释放GIL锁,线程进行锁竞争、切换线程,都会造成资源消耗,并且由于GIL锁存在,python里一个进程永远只能同时执行一个线程(拿到GIL的线程才能执行),导致在多核CPU上,Python的多线程效率并不高。

如果所示,三个线程交替执行,借此模拟并行。但某一时刻,程序中只有一个线程在执行,其他线程在等待其释放锁。

GIL 的特点:

1. Python在多线程下,每个线程的执行方式为:

  • 获取GIL
  • 执行代码直到sleep或者是python虚拟机将其挂起。
  • 释放GIL 

2. 一个CPU只能执行一个线程 ,例如一个CPU 有三个线程 ,首先线程A执行 ,然后
线程A达到释放条件进行释放GIL,线程B 和线程C 进行竞争GIL ,谁抢到GIL ,继续执行.

3. 一个进程里有多线程,但只有一个GIL 锁,不同的进程GIL 锁互不干扰,

4. 单个CPU多线程比多核多线程更快解释如下:

(单核内线程之间切换可以几乎达到无缝连接,但是在多核情况下一个线程 A释放GIL 锁,其他CPU上的线程都会进行竞争,但是有可能线程A 又抢到这个锁,导致其他几个CPU上被唤醒后的线程会醒着等待到切换时间后又进入待调度状态,
这样会造成线程颠簸(thrashing),导致效率更低.

5. 多核CPU和C 语言相比,python的多线程效率并不高.解释如下:

  • 释放GIL,和切换线程 需要消耗资源
  • 一个进程只能运行一个线程 (拿到GIL的线程才能执行),即使是多核CPU,也没办法让多个线程并行执行代码,只能是交替执行。

GIL释放

  1. 当一个线程遇到 I/O 任务时,将释放GIL,避免输入I/O操作浪费时间。这个特性是优于其他语言的。
  2. 计算密集型(CPU-bound)线程执行 100 次解释器的计步(ticks)时(计步可粗略看作 Python 虚拟机的指令),步数/时间到达阈值也会释放 GIL。但是效率依然不尽人意。

解决:

Python下想要充分利用多核CPU,采用多进程并发编程。这是因为多核下每个进程有各自独立的GIL,互不干扰,实现真正意义上的并行。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!