zoukankan      html  css  js  c++  java
  • GIL全局解释器锁

    GIL全局解释器锁

    Global Interpreter Lock

    全局解释器

    锁就是为了避免资源竞争造成数据的错乱

    为什么解释器要加锁

    1.启动解释器进程  python.exe

    2.解析你的py文件并执行它

    每个py程序中都必须有解释器参与,解释器其实就是一堆代码,相当多线程要调用同一个解释代码,共享就是竞争。竞争就要出事,所以需要要给解释器加上解释器。

    python中内存管理依赖于GC(一段用于回收内存的代码)也是一个线程。除了你自己开的线程,系统还有一些内置线程。就算你的代码不会竞争解释器,内置线程也可能会竞争,所以必须加上锁。

    GIL解锁的情况

    当一个线程遇到了IO操作,同时解释器也会自动解锁,去执行其他线程CPU会切换到其他程序。

    GIL性能的讨论

    解释器加锁以后:

      将导致所有线程只能开发,不能达到真正的并行,意味着同一时间只有一个cpu在处理你的线程所以给你的感觉是效率低。

    代码执行有两种状态

    阻塞IO 失去cpu的执行权(cpu 等待IO完成)

    非阻塞 代码正常执行,比如循环一千万次,中途cpu可能切换,很快就会回来(cpu在计算)

    案例:假如有32核心cpu要处理一个下载任务,网络速度100k/s,文件大小1024kb。

      如果你的代码中IO操作非常多,cpu性能不能直接绝对决定你的任务处理速度。

    对io密集程序和计算密集程序(多线程和多进程效率的差别)

    IO密集程序

    import time ,os
    from multiprocessing import Process
    from threading import Thread,current_thread
    
    def task():
        time.sleep(3)
    
    
    def task1():
        time.sleep(3)
    
    def task2():
        time.sleep(3)
    
    
    def task3():
        time.sleep(3)
    
    def task4():
        time.sleep(3)
    
    
    def task5():
        time.sleep(3)
    
    if __name__ == '__main__':
        start = time.time()
        #多进程处理io密集程序 耗时3.6272077560424805
        # p = Process(target=task)
        # p1 = Process(target=task1)
        # p2 = Process(target=task2)
        # p3 = Process(target=task3)
        # p4 = Process(target=task4)
        # p5 = Process(target=task5)
        
        #多线程处理io密集程序 耗时3.001171588897705(3秒是io固定长度)
        p = Thread(target=task)
        p1 = Thread(target=task1)
        p2 = Thread(target=task2)
        p3 = Thread(target=task3)
        p4 = Thread(target=task4)
        p5 = Thread(target=task5)
    
        p.start()
        p1.start()
        p2.start()
        p3.start()
        p4.start()
        p5.start()
    
        p.join()
        p1.join()
        p2.join()
        p3.join()
        p4.join()
        p5.join()
    
        print(time.time()-start)

    计算密集型程序

    from multiprocessing import Process
    from threading import Thread
    import time
    def task1():
        sum = 0
        for i in range(10000000):
            sum += i
    
    
    def task2():
        sum = 0
        for i in range(10000000):
            sum += i
    
    def task3():
        sum = 0
        for i in range(10000000):
            sum += i
    
    def task4():
        sum = 0
        for i in range(10000000):
            sum += i
    
    def task5():
        sum = 0
        for i in range(10000000):
            sum += i
    
    
    if __name__ == '__main__':
        #多进程处理运算密集型程序 2.9081664085388184
        start = time.time()
        # t1 = Process(target=task1)
        # t2 = Process(target=task2)
        # t3 = Process(target=task3)
        # t4 = Process(target=task4)
        # t5 = Process(target=task5)
    
        #多线程处理运算密集型程序 4.190239667892456
        t1 = Thread(target=task1)
        t2 = Thread(target=task2)
        t3 = Thread(target=task3)
        t4 = Thread(target=task4)
        t5 = Thread(target=task5)
    
    
        t1.start()
        t2.start()
        t3.start()
        t4.start()
        t5.start()
    
        t1.join()
        t2.join()
        t3.join()
        t4.join()
        t5.join()
    
        print(time.time()-start)

    可以得出结论

    在计算密集程序中使用多进程处理效率更高

    在io操作密集的程序中使用多线程处理效率更加高

  • 相关阅读:
    tf-idf sklearn
    特征工程——特征预处理
    dict 字典
    特征预处理——特征表达
    特征工程之特征选择
    机器学习技巧学习
    dataframe去重 drop_duplicates
    dataframe 转为list
    XGboost
    StratifiedShuffleSplit()函数 实现对数据集的划分
  • 原文地址:https://www.cnblogs.com/msj513/p/9947333.html
Copyright © 2011-2022 走看看