zoukankan      html  css  js  c++  java
  • 并发编程中的GIL锁(全局解释器锁)自己理解的他为啥存在

    自己的分析

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

    -这里涉及到一个小知识
    我们知道在一个语言中,要对一个变量名进行赋值操作,就不是表面所看见的拿到内存中所存储的值,再拿到变量名,进行一个
    等号的赋值操作,这样的理解是错误的。他其实大致的原理是这样子的:如下图

    1568790454945

    也就是说我们再执行一个简单的赋值操作的时候,会经过好几道步骤,然后我们知道线程再运行的时候,可能会有多个线程同时运
    行,这个时候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。

  • 相关阅读:
    js动画(三)
    js动画(二)
    css内容生成器
    css选择器基本属性
    css样式图片、渐变、相关小知识
    wed网页开发面试笔试必备小知识
    html5.边框属性相关知识点
    伪类选择符
    窗口尺寸小用法
    css3选择符使用个人理解。
  • 原文地址:https://www.cnblogs.com/xiongchao0823/p/11542606.html
Copyright © 2011-2022 走看看