• Python 36 GIL全局解释器锁 、vs自定义互斥锁


    一:GIL全局解释器锁介绍

    CPython中,全局解释器锁(或GIL)是一个互斥锁, 它阻止多个本机线程同时执行Python字节码。译文:之所以需要这个锁, 主要是因为CPython的内存管理不是线程安全的。(然而,由于GIL的存在, 其他特性已经变得依赖于它所执行的保证。)
    1. 什么是GIL全局解释器锁
    GIL本质就是一把互斥锁,相当于执行权限,每个进程内都会存在一把GIL,同一进程内的多个线程必须抢到GIL之后才能使用Cpython解释器来执行自己的代码,即同一进程下的多个线程无法实现并行但是可以实现并发在Cpython解释器下,如果想实现并行可以开启多个进程
    2. 为何要有GIL
    因为Cpython解释器的垃圾回收机制不是线程安全的
    3. 如何用GIL
    有了GIL,应该如何处理并发
    from threading import Thread
    import time
    
    def task(name):
        print('%s is running' %name)
        time.sleep(2)
    
    if __name__ == '__main__':
        t1=Thread(target=task,args=('线程1',))
        t2=Thread(target=task,args=('线程1',))
        t3=Thread(target=task,args=('线程1',))
        t1.start()
        t2.start()
        t3.start()
    View Code
     

    二:多线程性能测试

    from multiprocessing import Process
    from threading import Thread
    import os,time
    
    def work():
        res=0
        for i in range(100000000):
            res*=i
    
    if __name__ == '__main__':
        l=[]
        print(os.cpu_count())
        start=time.time()
        for i in range(6):
            # p=Process(target=work)
            p=Thread(target=work)
            l.append(p)
            p.start()
        for p in l:
            p.join()
        stop=time.time()
        print('run time is %s' %(stop-start)) #4.271663427352905
    计算密集型:应该使用多进程
    from multiprocessing import Process
    from threading import Thread
    import threading
    import os, time
    
    
    def work():
        time.sleep(2)
    
    
    if __name__ == '__main__':
        l = []
        start = time.time()
        for i in range(300):
            # p=Process(target=work) #2.225289821624756
            p = Thread(target=work)  # 2.002105951309204
            l.append(p)
            p.start()
        for p in l:
            p.join()
        stop = time.time()
        print('run time is %s' % (stop - start))
    IO密集型: 应该开启多线程

    三:GIL vs自定义互斥锁

    from threading import Thread,Lock
    import time
    
    mutex=Lock()
    n=100
    def task():
        global n
        with mutex:
            temp=n
            time.sleep(0.1)
            n=temp-1
    
    if __name__ == '__main__':
        l=[]
        for i in range(100):
            t=Thread(target=task)
            l.append(t)
            t.start()
    
        for t in l:
            t.join()
        print(n)

    四、关于线程的故事
    线程小故事

  • 相关阅读:
    NConsoler 介绍
    HOWTO:批量删除存储过程和表
    HOWTO:使ASP.NET网站Forms验证可以指定多个登录页面
    [架构模式实践]如何不让第三方服务/组件的故障阻碍开发和测试进度
    GDI+学习笔记
    脚印: SD2C 2009 参会小记(非技术篇)
    Expression Web使用问题,相关资源及今日阅读
    HOWTO:FirePHP乱码问题解决
    [ECSHOP挖寶]用戶注銷過程
    励志好文
  • 原文地址:https://www.cnblogs.com/zedong/p/9606541.html
Copyright © 2020-2023  润新知