• Python-为什么产生了GIL锁?


    因为在python设计出来的年代根本就没有多核这一说法,都是单核cpu,因为线程是cpu执行的最小单位,在单核情况下,我们的python进程中就算开了多条线程,在同一个时刻也只有一个线程被cpu调度执行,当某一个线程在执行时,其他线程都是停止工作的,所以不会同时对一个数据进行操作导致数据混乱。

    但是随着发展,出现了多核cpu,那么多个cpu就能执行多条线程,而我们的python解释器是一个进程,在进程中,线程是数据共享的。假设现在cpu1运行线程1,cpu2运行线程2,如果线程1与线程2正好都需要对同一个变量进行操作,就会产生并发数据不安全的问题。(上面不会出现数据安全问题是因为只有一个cpu,也就只有一条线程在运行。不会出现多条线程同时操作一个数据)。所以龟叔想了一个办法,就在cpython解释器上加了一把互斥锁,也就是GIL,在cpython解释器中,必须要获得这把互斥锁,线程才能被调度执行,这就又保证了在同一情况,只有拿到锁的那个线程会被运行,保证了数据安全,也就是只有一个cpu在运行。这就是大家诟病的cpython慢的原因,因为GIL锁是互斥锁,只能被一个线程获得,那么cpu再多也没用了,因为抢不到锁就得等着,这就是cpython无法利用多核优势的原理。

    后来龟叔一看,这样性能太差不行啊,所以他允许开多进程,开了多个进程那么就有多个python解释器进程,可以有多个GIL锁,也就可以有多个线程同时执行,并且因为进程之间是数据隔离的,也就不会产生数据混乱的问题。(首先进程间数据隔离了,不会相互改,并且在各自的进程中又有GIL锁,又保证各个线程数据的安全)。

    本人在这里产生了一个问题,就是在一个线程中,当我们定义一个变量,比如a=1时候,我们知道,python定义一个变量,是先产生一个a放在栈区,然后在堆区产生数据1,然后把对应关系建立,此时a的引用计数才为1,那么如果当我们在a刚产生的时候,线程的时间片正好到了,那么此时a的引用计数为0,这个线程的GIL锁释放,又正好被垃圾回收线程抢到了,按照垃圾回收的原理,a应该被回收,那么GIL锁不是就无法保护我们的数据安全了吗?

    其实答案很简单,因为在python在,变量的定义与赋值是一个原子性操作,原子性操作是不会被中断的,他不会被cpu的线程调度打断,即如果他开始了,那么一直到他结束,cpu都不会让出他的执行。所以也就不会产生上述的问题,其实在python中,有大量的原子性操作,即使像字典和类成员赋值这样的操作也是原子性。

  • 相关阅读:
    看net2.0头晕眼花,是不是该做个具体的程序呢
    安装SQLServer2000时,提示"以前的某个程序安装已在安装计算机上创建挂起的文件操作。运行安装程序之前必须重新启动计算机"
    刚装的WIN7,用了一下午,记一下备忘
    不同系统开启和关闭fso的方法(转)
    希腊字母以及发音
    meta 标签的作用
    电信禁止路由上网的最佳破解方法(转)
    安装系统
    网络工程师笔记
    GHOST操作
  • 原文地址:https://www.cnblogs.com/chiyun/p/14066030.html
Copyright © 2020-2023  润新知