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释放
- 当一个线程遇到 I/O 任务时,将释放GIL,避免输入I/O操作浪费时间。这个特性是优于其他语言的。
- 计算密集型(CPU-bound)线程执行 100 次解释器的计步(ticks)时(计步可粗略看作 Python 虚拟机的指令),步数/时间到达阈值也会释放 GIL。但是效率依然不尽人意。
解决:
Python下想要充分利用多核CPU,采用多进程并发编程。这是因为多核下每个进程有各自独立的GIL,互不干扰,实现真正意义上的并行。
来源:https://blog.csdn.net/qq_42122036/article/details/102722519