• 全局解释器和协程


    1.全局解释器锁

    1.1python解释器:

    ​ -Cpython c语言

    ​ -Jpython java

    1.2GIL :全局解释器

    ​ -翻译:在同一个进程下开启的多线程,同一时刻只能有有一个线程执行,因为cpython的内存管理不是线程安全。

    ​ -GIL全局解释器,本质上是一把互斥锁,保证数据安全

    ​ 在Cpython解释器中,同一个进程下开启多个线程,同一时刻只能有一个线程执行,无法利用多核优势。

    ​ -为什么要有全局解释器锁:

    ​ -没有锁

    ​ -GIL全局解释器锁的优点:

    ​ -优点:

    ​ 保证数据的安全

    ​ -缺点:

    ​ 单个进程下,开启多个线程,牺牲执行效率了,无法实现并行,只能实现并发。

    ​ -IO密集型: 多线程

    ​ -计算机密集型:多进程

    import time
    from threading import Thread
    n = 100
    def task():
        global n
        m = n
        time.sleep(3)
        n =m -1####实际产生了10个99  最后一个只打印了一个n
        
        #print(n)
    
    if __name__ == '__main__':
        list = []
        for line in range(10):
            t = Thread(target = task)
            t.start()
            list.append(t)
    
        for t in list:
            t.join()
        print(n)
        >>>>>>>>>>>>>>>>>>>>>>
        99
    

    2.协程

    -定义:

    ​ -进程:资源单位

    ​ -线程:执行单位

    ​ -协程:单线程西实现并发

    ​ -在IO密集的情况下,使用协程能提高最高效率

    注意:协程不是任何单位,使用协程能提高最高效率

    协程的目的:

    ​ -手动实现“遇到IO切换+保存状态” ,因为是在单线程下,控制单线程的多个任务在一个任务遇到io,就切换到另外一个任务执行,这样保证了,线程能够最大限度的处于就绪化,即随时都可以被cpu执行的状态,可以去欺骗操作系统,让操作系统误以为没有io操作,从而将cpu的执行权限交给你。

    ​ -必须只有单线程实现并发,

    ​ -协程指的是单个线程,一旦线程出现阻塞,及那个会阻塞整个线程

    from gevent import monkey  # 猴子补丁   
    monkey.patch_all()  # 监听所有的任务是否有IO操作 
    #上面的2个必须写在文件的开头,在time socket的模块之前,这样形成的io 可以直接识别
    from gevent import spawn  # spawn(任务)  spawn(函数名,参数,参数)
    from gevent import joinall
    import time
    
    def task1():
        print('start from task1...')
        time.sleep(1)
        print('end from task1...')
    
    def task2():
        print('start from task2...')
        time.sleep(3)
        print('end from task2...')
    
    def task3():
        print('start from task3...')
        time.sleep(5)
        print('end from task3...')
    
    
    if __name__ == '__main__':
    
        start_time = time.time()
        sp1 = spawn(task1)
        sp2 = spawn(task2)
        sp3 = spawn(task3)
        # sp1.start()
        # sp2.start()
        # sp3.start()
        # sp1.join()
        # sp2.join()
        # sp3.join()
        joinall([sp1, sp2, sp3])
    
        end_time = time.time()
    
        print(f'消耗时间: {end_time - start_time}')
    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    start task1...
    start task2...
    start task3...
    end task1...
    end task2...
    end task3...
    消耗时间:3.0044186115264893
    
    

    3.使用多线程提高效率

    from threading import Thread
    from multiprocessing import Process
    import time
    
    #计算密集型任务
    def task1():
        i = 10
        for line in range(1000000):
            i += 1
    
    #io密集型任务
    def task2():
        time.sleep(3)
    
    if __name__ == '__main__':
        #测试多进程
        #计算密集型
        a = time.time()
        list1 = []
        for line in range(6):
            p = Process(target = task1)
            print(p)
            p.start()
            list1.append(p)
    
        for p in list1:
            p.join()
        b = time.time()
        print(f'计算进程密集型消耗的时间:{b-a}')
    
        #测试IO密集型
        a = time.time()
        list2 = []
        for line in range(6):
            p = Process(target = task2)
            p.start()
            list2.append(p)
    
        for p in list2:
            p.join()
        b = time.time()
        print(f'IO进程密集型消耗时间:{b-a}')
    
        #2.测试多线程的
        #测试计算密集型
        a = time.time()
        list1 = []
        for line in range(6):
            p = Thread(target = task1)
            p.start()
            list1.append(p)
    
        for p in list1:
            p.join()
            b = time.time()
        print(f'计算线程密集型消耗时间:{b -a}')
    
        #测试IO密集型
        a = time.time()
        list1 = []
        for line in range(6):
            p = Thread(target = task2)
            p.start()
            list1.append(p)
    
        for p in list1:
            p.join()
        b = time.time()
        print(f'IO线程密集型的消耗时间:{b - a}')
        >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    计算进程密集型消耗的时间:0.3511178493499756
    IO进程密集型消耗时间:3.215735912322998
    计算线程密集型消耗时间:0.43486547470092773
    IO线程密集型的消耗时间:3.003101110458374
    
  • 相关阅读:
    如何用jquery实现实时监控浏览器宽度
    关于oracle with as用法
    SQL查询语句,怎样查询重复数据
    Axure RP Pro7.0的key注册码加汉化非破解
    秦曾昌人工智能课程---7、决策树集成学习Tree Ensembles
    秒懂机器学习---分类回归树CART
    秒懂机器学习---朴素贝叶斯
    秒懂机器学习---k临近算法(KNN)
    秒懂机器学习---机器学习无法逃避的梯度下降法
    秒懂机器学习---当机器学习遇上决策树....
  • 原文地址:https://www.cnblogs.com/bs2019/p/12037237.html
Copyright © 2020-2023  润新知