1、GIL概念
GIL(Global Interpreter Lock)全局解释器锁,这是解释器内部的一把锁,确切一点说是CPython解释器内部的一把锁,所以要注意区分 这和我们在Python代码中使用Lock不是一个层面的概念。
言外之意,就是全局解释器就是为了锁定整个解释器内部的全局资源,每个线程想要运行首先获取GIL,而GIL本身又是一把互斥锁,造成所有线程只能一个一个one-by-one-并发-交替的执行。
2、GIL产生的背景
在CPython解释内部运行多个线程的时候,每个线程都需要解释器内部申请相应的全局资源,由于C语言本身比较底层造成CPython在管理所有全局资源的时候并不能应对所有线程同时的资源请求,因此为了防止资源竞争而发生错误,对所有线程申请全局资源增加了限制-全局解释器锁。
CPython 多线程:
- 存在GIL
- 适用于 I/O密集型程序 <多线程效率比单线程高>
- 不适于 CPU密集型程序 <多线程效率比单线程低>
3、GIL什么时候释放
(1)在当前线程执行超时后会自动释放。
(2)在当前线程执行阻塞操作时会自动释放。
(3)当前执行完成时。
4、存在GIL,线程在获取全局变量时还用加Lock互斥锁吗?
用户操作全局数据还需要加Lock,因为GIL的释放时机我们无法控制-操作非常可能并没有完成,而不像Lock那样我们用完才释放(操作完整)。GIL控制的是线程的切换,而Lock是控制函数的执行。
5、GIL无法有效利用多核cpu?
一个进程内的线程想要进入CPU执行,必须先要拿到 GIL ,但是,同一时间只能有一个线程可以拿到,GIL 的释放逻辑 是 tacks 计数到达 100 或遇到 IO操作进行释放。
在单进程的多线程下,即使是多核 CPU,因为有GIL,在 python里仍然是单线程。单进程的 GIL 会影响 python 的 开发效率。
6、如何解决GIL?
可以通过多进程的方式来解决这种情况,因为 GIL 针对于 某个进程的 多线程,开启多个进程解决 GIL 带来的影响