• GIL锁


    GIL锁                                                                                在CPython中,这个全局解释器锁,也称GIL,是一个互斥锁,防止多个线程在同一时间执行pyonty字节码,这个锁是非常重要的,因为cpython的内存管理非线程安全的,很多其他的特性依赖于GIL,所以即使它影响了程序效率也无法将其直接去掉。                                                       总结:在cpython中,GIL会把线程的并行变成串行,导致效率降低(需要的是知道的是,解释器并不是只有cpython,还有pypy,jpython等等。GIL也存在与cpython中,这并不是python这门语言的问题,而是cpython解释器的问题)

    GIL与GC的孽缘

    在使用Python中进行编程时,程序员无需参与内存的管理工作,这是因为Python有自带的内存管理机制,简称GC。那么GC与GIL有什么关联?

    要搞清楚这个问题,需先了解GC的工作原理,Python中内存管理使用的是引用计数,每个数会被加上一个整型的计数器,表示这个数据被引用的次数,当这个整数变为0时则表示该数据已经没有人使用,成了垃圾数据。

    当内存占用达到某个阈值时,GC会将其他线程挂起,然后执行垃圾清理操作,垃圾清理也是一串代码,也就需要一条线程来执行。

    示例代码:

    from threading import Thread
    def task():
    a = 10
    print(a)

    # 开启三个子线程执行task函数
    Thread(target=task).start()
    Thread(target=task).start()
    Thread(target=task).start()

    通过上图可以看出,GC与其他线程都在竞争解释器的执行权,而CPU何时切换,以及切换到哪个线程都是无法预支的,这样一来就造成了竞争问题,假设线程1正在定义变量a=10,而定义变量第一步会先到到内存中申请空间把10存进去,第二步将10的内存地址与变量名a进行绑定,如果在执行完第一步后,CPU切换到了GC线程,GC线程发现10的地址引用计数为0则将其当成垃圾进行了清理,等CPU再次切换到线程1时,刚刚保存的数据10已经被清理掉了,导致无法正常定义变量。

    当然其他一些涉及到内存的操作同样可能产生问题问题,为了避免GC与其他线程竞争解释器带来的问题,CPython简单粗暴的给解释器加了互斥锁,如下图所示:有了GIL后,多个线程将不可能在同一时间使用解释器,从而保证了解释器的数据安全。

    GIL的加锁与解锁时机

    加锁的时机:在调用解释器时立即加锁

    解锁时机:

    • 当前线程遇到了IO时释放

    • 当前线程执行时间超过设定值时释放

      GIL的优点:

      • 保证了CPython中的内存管理是线程安全的

      GIL的缺点:

      • 互斥锁的特性使得多线程无法并行

       

      但我们并不能因此就否认Python这门语言,其原因如下:

      1. GIL仅仅在CPython解释器中存在,在其他的解释器中没有,并不是Python这门语言的缺点

      2. 在单核处理器下,多线程之间本来就无法真正的并行执行

      3. 在多核处理下,运算效率的确是比单核处理器高,但是要知道现代应用程序多数都是基于网络的(qq,微信,爬虫,浏览器等等),CPU的运行效率是无法决定网络速度的,而网络的速度是远远比不上处理器的运算速度,则意味着每次处理器在执行运算前都需要等待网络IO,这样一来多核优势也就没有那么明显了

       

      1. 总结:

        1.单核下无论是IO密集还是计算密集GIL都不会产生任何影响

        2.多核下对于IO密集任务,GIL会有细微的影响,基本可以忽略

        3.Cpython中IO密集任务应该采用多线程,计算密集型应该采用多进程

      另外:之所以广泛采用CPython解释器,就是因为大量的应用程序都是IO密集型的,还有另一个很重要的原因是CPython可以无缝对接各种C语言实现的库,这对于一些数学计算相关的应用程序而言非常的happy,直接就能使用各种现成的算法

       

  • 相关阅读:
    【LOJ】#2184. 「SDOI2015」星际战争
    【LOJ】#2181. 「SDOI2015」排序
    求解任意多边形的面积(平面内)
    认识基本的mfc控件
    .net学习之路——调试程序
    小白详细讲解快速幂--杭电oj2035-A^B
    模拟停车场问题
    初识mfc
    2034-人见人爱A-B(c++实现)
    3032-杨辉三角
  • 原文地址:https://www.cnblogs.com/tangda/p/10500950.html
Copyright © 2020-2023  润新知