zoukankan      html  css  js  c++  java
  • GIL、进/线程池、同/异步、阻/非阻塞

    1 GIL:全局解释器锁
    GIL本质就是一把互斥锁,是夹在解释器身上的,
    同一个进程内的所有线程都需要先抢到GIL锁,才能执行解释器代码

    2、GIL的优缺点:
    优点:
    保证Cpython解释器内存管理的线程安全

    缺点:
    同一进程内所有的线程同一时刻只能有一个执行,
    也就说Cpython解释器的多线程无法实现并行
    from threading import Thread,current_thread
    import time
    
    def task():
        print('%s is running' %current_thread().name)
        time.sleep(3)
        print('%s is done' %current_thread().name)
    
    
    if __name__ == '__main__':
        t1=Thread(target=task)
        t2=Thread(target=task)
        t3=Thread(target=task)
        t1.start()
        t2.start()
        t3.start()
    验证

    一、 计算密集型应该使用多进程:

    #frommultiprocessingimportProcess#fromthreadingimportThread##importtime##importos##print(os.cpu_count())##deftask1():#res=0#foriinrange(1,100000000):#res+=i##deftask2():#res=0#foriinrange(1,100000000):#res+=i##deftask3():#res=0#foriinrange(1,100000000):#res+=i##deftask4():#res=0#foriinrange(1,100000000):#res+=i##if__name__=='__main__':##p1=Process(target=task1)##p2=Process(target=task2)##p3=Process(target=task3)##p4=Process(target=task4)##p1=Thread(target=task1)#p2=Thread(target=task2)#p3=Thread(target=task3)#p4=Thread(target=task4)#start_time=time.time()#p1.start()#p2.start()#p3.start()#p4.start()#p1.join()#p2.join()#p3.join()#p4.join()#stop_time=time.time()#print(stop_time-start_time)
    多进程

    二、IO密集型应该使用多线程:

    from multiprocessing import Process
    from threading import Thread
    
    import time
    
    
    def task1():
        time.sleep(3)
    
    def task2():
        time.sleep(3)
    
    def task3():
        time.sleep(3)
    
    def task4():
        time.sleep(3)
    
    if __name__ == '__main__':
        # p1=Process(target=task1)
        # p2=Process(target=task2)
        # p3=Process(target=task3)
        # p4=Process(target=task4)
    
        # p1=Thread(target=task1)
        # p2=Thread(target=task2)
        # p3=Thread(target=task3)
        # p4=Thread(target=task4)
        # start_time=time.time()
        # p1.start()
        # p2.start()
        # p3.start()
        # p4.start()
        # p1.join()
        # p2.join()
        # p3.join()
        # p4.join()
        # stop_time=time.time()
        # print(stop_time - start_time) #3.138049364089966
    
        p_l=[]
        start_time=time.time()
    
        for i in range(500):
            p=Thread(target=task1)
            p_l.append(p)
            p.start()
    
        for p in p_l:
            p.join()
    
        print(time.time() - start_time)
    多线程

    进程池与线程池:

    为什么要用“池”?

       池子使用来限制并发的任务数目,限制我们的计算机在一个自己可承受的范围内去并发地执行任务

      池子内什么时候装进程:并发的任务属于计算密集型

      池子内什么时候装线程:并发的任务属于IO密集型

    # from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
    # import time,os,random
    #
    # def task(x):
    #     print('%s 接客' %os.getpid())
    #     time.sleep(random.randint(2,5))
    #     return x**2
    #
    # if __name__ == '__main__':
    #     p=ProcessPoolExecutor() # 默认开启的进程数是cpu的核数
    #
    #     # alex,武佩奇,杨里,吴晨芋,张三
    #
    #     for i in range(20):
    #         p.submit(task,i)
    
    from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
    import time,os,random
    
    def task(x):
        print('%s 接客' %x)
        time.sleep(random.randint(2,5))
        return x**2
    
    if __name__ == '__main__':
        p=ThreadPoolExecutor(4) # 默认开启的线程数是cpu的核数*5
    
        # alex,武佩奇,杨里,吴晨芋,张三
    
        for i in range(20):
            p.submit(task,i)
    代码演示

    阻塞与非阻塞、同步与异步:

    1、阻塞与非阻塞指的是程序的两种运行状态

      阻塞:遇到IO就发生阻塞,程序一旦遇到阻塞操作就会停在原地,并且立刻释放CPU资源

      非阻塞(就绪态或运行态):没有遇到IO操作,或者通过某种手段让程序即便是遇到IO操作也不会停在原地,执行其他操作,力求尽可能多的占有CPU

    2、同步与异步指的是提交任务的两种方式:

      同步调用:提交完任务后,就在原地等待,直到任务运行完毕后,拿到任务的返回值,才继续执行下一行代码

      异步调用:提交完任务后,不在原地等待,直接执行下一行代码,结果?

    from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
    import time,os,random
    
    def task(x):
        print('%s 接客' %x)
        time.sleep(random.randint(1,3))
        return x**2
    
    if __name__ == '__main__':
        # 异步调用
        # p=ThreadPoolExecutor(4) # 默认开启的线程数是cpu的核数*5
        #
        # # alex,武佩奇,杨里,吴晨芋,张三
        #
        # obj_l=[]
        # for i in range(10):
        #     obj=p.submit(task,i)
        #     obj_l.append(obj)
        #
        # # p.close()
        # # p.join()
        # p.shutdown(wait=True)
        #
        # print(obj_l[3].result())
        # print('主')
    异步调用
        # 同步调用
        p=ThreadPoolExecutor(4) # 默认开启的线程数是cpu的核数*5
    
        # alex,武佩奇,杨里,吴晨芋,张三
    
        for i in range(10):
            res=p.submit(task,i).result()
    
        print('')
    同步调用
  • 相关阅读:
    OAuth2.0说明文档
    CentOS直接解压可用的memcached、nginx、keepalived
    CentOS离线安装GCC编译环境
    [交通安全]电动自行车认定为非机动车的文件
    修改sublime列编辑快捷键
    手机号归属地接口
    ubuntu下typora的gitee图床配置-----基于picgo
    spyder无法切换中文输入法
    lightgbm直方图算法
    xgboost原理分析
  • 原文地址:https://www.cnblogs.com/TF511/p/9954193.html
Copyright © 2011-2022 走看看