GIL
释义
Global Interpreter Lock 全局解释器锁
官方解释:
'''
In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple
native threads from executing Python bytecodes at once. This lock is necessary mainly
because CPython’s memory management is not thread-safe. (However, since the GIL
exists, other features have grown to depend on the guarantees that it enforces.)
'''在 Cpython中,这个全局解释器锁 或者 称为GIL,是一个互斥锁. 是为了防止多个本地线程同一时间执行python字节码,
这个锁是非常重要的因为Cpython的内存管理是非线程安全的, ,然而这个GIL有存在的必要性, 因为有很多已经存在的代码,需要依赖这个锁
非线程安全 即 多个线程访问同一个资源,会有问题
线程安全 即 多个线程访问同一个资源,不会有问题
GIL为CPython独有
CPython中有一个互斥锁,防止线程同一时间执行python代码
该锁只存在Cpython中,这并不是Python这们语言的 除了Cpython之外 Jpython, pypy,解释器 没有
使用Cpython的原因
之所以使用Cpython的原因??
C编译过的结果可以计算机直接识别
最主要的语言,C语言以后大量现成的,库(算法,通讯),Cpython可以无缝连接C语言的任何现成代码
python 胶水 就是这也能干 那也能干
这样设计GIL的原因
为什么Cpython要这么设计???
Cpython诞生于1991年 而多核处理器诞生2004年
当时不需要考虑多核效率问题
现在为什么不拿掉这个锁,因为这期间,很多已经完成的代码都依赖于这个锁,如果直接拿到,这些代码全得该,成本太大了
GIL锁的加锁与解锁时机
加锁: 只有有一个线程要使用解释器就立马枷锁
释放:
该线程任务结束
该线程遇到IO
该线程使用解释器过长 默认100纳秒
GIL给我们造成的影响
多线程不能并行
案例
有一个下载任务 要从网络中下载一个文件 大小1G
和转换 任务 使用input 转为大写输出
上述任务并行执行,耗时也不会有太大的提升,反而开启多进程会浪费更多资源
这种任务称之为IO密集型任务,大量的时间都花在IO等待
这类问题使用多线程.
计算密集型任务
图像处理,语音处理,大数据分析
解决方案
区分任务类型
如果是IO密集使用多线程
如果是计算密集使用多进程
GIL锁与自定义锁的关系
都是互斥锁
为什么有了GIL还需要自己加锁
GIL是加在解释器上的,只能锁住,解释器内部的资源,但是无法锁住我们自己开启资源
例如: 我们自己开启了一个json文件,多个线程要同时访问, 如果第一个线程写入数据写到一半,执行超时了,另一个线程过来接着写,就会产生问题,
自己开启共享资源还得自己所锁
像是申请内存 保存数据等等就不需要我们程序员考虑了 GIL已经搞定了