加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

并发编程中的GIL锁(全局解释器锁)自己理解的他为啥存在

发布时间:2020-12-20 10:41:25 所属栏目:Python 来源:网络整理
导读:自己的分析 GIL锁就是一个全局解释器锁 也就是python中因为有垃圾回收机制的存在。垃圾回收机制也是一个线程,如果所有的线程都可以使用cpu的不同资源(也就是多核 cpu并行处理线程的情况) -这里涉及到一个小知识 我们知道在一个语言中,要对一个变量名进行

自己的分析

GIL锁就是一个全局解释器锁
也就是python中因为有垃圾回收机制的存在。垃圾回收机制也是一个线程,如果所有的线程都可以使用cpu的不同资源(也就是多核
cpu并行处理线程的情况)

-这里涉及到一个小知识
我们知道在一个语言中,要对一个变量名进行赋值操作,就不是表面所看见的拿到内存中所存储的值,再拿到变量名,进行一个
等号的赋值操作,这样的理解是错误的。他其实大致的原理是这样子的:如下图(tmp并不是一个变量名,我也忘记他到底是个啥
了,百度翻译告诉他是一个终端监控程序!!!)

也就是说我们再执行一个简单的赋值操作的时候,会经过好几道步骤,然后我们知道线程再运行的时候,可能会有多个线程同时运
行,这个时候cpu有个“反复横跳”的机制,也就是好几个线程之间跳来跳去,让咱们的线程看起来像是并行(这里假设可以并行两个,
但是另外一个线程过来了,所以才会可能中断正在执行的线程,假设!!!),而且如果一个线程运行久了,cpu也就会中断线程、
保护现场,之后运行其他的线程,这个时候可能会是在解释器赋值的操作的时候,我们都知道线程间的数据是共享的,他们可能会
去修改同一个数据,而我们途中的 tmp = 10 就相当于获取了需要修改的值,还没有进行操作,cpu把我们中断了,这个时候去运行
其他的线程,也去修改这个值,然后他们都获取到的是同一个没有经过修改的一样的值,就会造成少修改一次的情况发生。造成数
据出错,如果说我们的垃圾回收机制在此时生效,因为垃圾回收机制也是一个线程,他如果生效了,因为当时被中断的线程没有完
成赋值,所以那个值的引用技术为0,就会造成数据被垃圾回收机制回收,造成一个线程没有值了,所以就有了全局解释器锁,让
我们的线程是单个运行的,就不会造成数据被垃圾回收机制回收。

但是这样也会造成我们的线程是没有办法实现多核cpu并行的操作的,他就只会是并发,如果要去实现并行也是可以的,就必须去开
进程,一个进程里面只有一个线程去运行,就可以实现并行但是站在的角度不同的话,因为cpu是一个运算的部件,所以说如果我们
的代码是计算特别复杂的话,可以使用多进程并行的方式去执行,但是我们后端的操作中主要是io比计算多,所以使用多线程并发的
方式其实是比多进程要快的,因为创建线程的时间要远远小于创建进程的时间。

正规的分析

Python代码的执行由Python虚拟机(也叫解释器主循环)来控制。Python在设计之初就考虑到要在主循环中,同时只有一个线程在执行。虽然 Python 解释器中可以“运行”多个线程,但在任意时刻只有一个线程在解释器中运行。

对Python虚拟机的访问由全局解释器锁(GIL)来控制,正是这个锁能保证同一时刻只有一个线程在运行。

在多线程环境中,Python 虚拟机按以下方式执行:

设置 GIL; 切换到一个线程去运行; 运行指定数量的字节码指令或者线程主动让出控制(可以调用 time.sleep(0)); 把线程设置为睡眠状态; 解锁 GIL; 再次重复以上所有步骤。 在调用外部代码(如 C/C++扩展函数)的时候,GIL将会被锁定,直到这个函数结束为止(由于在这期间没有Python的字节码被运行,所以不会做线程切换)编写扩展的程序员可以主动解锁GIL。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读