PYTHON GIL 理解

作者: 彩色系 | 来源:发表于2017-08-03 11:55 被阅读13次

    在理解GIL前 首先要理解下python的线程。

    线程执行过程

    上图是线程的执行过程。可以看到 GIL确保一个时刻只有一个线程执行。在碰到阻塞 比如IO等待时释放GIL。

    一开始

    第一步

    当线程一遇到一个IO事件后,释放掉GIL

    释放GIL

    线程二拿到锁,进行上下文切换

    切换

    有时会出现两个线程都是可用的情况

    都可用

    这时就通过系统的优先级队列来调度。从就绪队列中拿到优先级高的,然后进行运算。

    enter image description here

    GIL的影响

    通过一个简单的countdown代码来测试

    num=1000000
    def threaded_at_once():
        threads = [num//2 for i in range(20)]
        results = pool.map(countdown, threads)
    
    def normal():
        for i in range(concurrent):
            countdown(num)
    
    testnum = 10
    a = timeit(normal, number=testnum)
    b = timeit(threaded_at_once, number=testnum)
    print('Normal', a)
    print('thread', b)
    
    # py3.5.2
    # Normal 6.854097206157869
    # thread 6.9655090331886695
    # py3.6
    # Normal 9.051292152972469
    # thread 8.782672920645473
    # py2.7
    # Normal 3.92715933198
    # thread 12.6787057864
    

    可以看到不同版本的python较大这个是由于内部线程切换的逻辑不同带来的。

    整体来看gil对程序还是有影响的。使用了多线程并没有带来很显著的提升。

    在cpython的解释器中有这样一个函数。

    sys.setcheckinterval(interval)
    设置解释器的“检查间隔”。此整数值确定解释器检查周期性事件(例如线程切换和信号处理程序)
    的频率。默认值为 100,表示每100个Python虚拟指令执行一次检查。将其设置为较大的值可以提高
    使用线程的程序的性能。将其设置为值 <= 0检查每个虚拟指令,最大化响应度以及开销。
    3.2 版后已移除: 此函数不再有效果,因为线程切换和异步任务的内部逻辑已被重写。
    请改用 setswitchinterval()。
    

    对于CPU密集的任务 GIL才会有影响。

    为什么cpython要使用gil?

    gil的好处:
    增加单线程处理的速度
    易于集成的C库通常不是线程安全的
    在io密集任务线程是更好的选择
    使得C扩展更容易编写
    

    为什么有时有了GIL还需要自己手动给一些程序加锁?

    GIL锁的层面是python 字节码层面的
    而自己实现同步时用的锁是python层面的,相当于是用户锁
    执行的粒度不同
    一个简单的加一操作有多个原子操作。gil只确保在一个原子操作上是安全的
               dis.dis(lambda x:x+1)
               0 LOAD_FAST                0 (x)
              3 LOAD_CONST               1 (1)
              6 BINARY_ADD
              7 RETURN_VALUE
    

    在遇到性能瓶颈时,将这一部分拿出来,用C扩展,可以获得很大的提升。

    https://www.yunxcloud.cn/post/136
    参考

    http://www.dabeaz.com/python/GIL.pdf

    http://www.dabeaz.com/python/UnderstandingGIL.pdf

    https://softwareengineering.stackexchange.com/questions/186889/why-was-python-written-with-the-gil

    博客 https://www.97up.cn/post/148

    https://wiki.python.org/moin/GlobalInterpreterLock

    相关文章

      网友评论

        本文标题:PYTHON GIL 理解

        本文链接:https://www.haomeiwen.com/subject/fbxplxtx.html