zoukankan      html  css  js  c++  java
  • 并发编程-协程、池,io模型

    一、线程池、进程池

      开进程、开线程都需要消耗资源,只不过两者比较的情况线程消耗的资源比较少

      在计算机能够承受范围之内最大限度的利用计算机

    什么是池?

      在保证计算机硬件安全的情况下最大限度的利用计算机

      池其实是降低了程序的运行效率,但是保证了计算机硬件的安全

      (硬件的发展跟不上软件的速度)

    # 调用
    from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
    
    # 建池子
    pool = ProcessPoolExecutor()   # 默认是当前计算机cpu的个数
    pool = ThreadPoolExecutor(5)  # 括号可穿参数,不传默认代表cpu个数*5
    
    res = pool.submit(task,i).add_done_callback(call_back)
    # 提交任务,绑定一个回调函数,一旦该任务有结果,立刻执行对于的回调函数
    
    res.result()  # 原地等待任务的返回结果
    
    pool.shutdown()  # 关闭池子,等待池子中所有的任务执行完毕之后,才会往下运行代码
    import time
    from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
    
    
    # pool = ThreadPoolExecutor(5)  # 括号内可以传参数指定线程池内的线程个数
    # # # 也可以不传,不传默认是当前所在计算机的 CPU的个数乘5
    import os
    
    pool = ProcessPoolExecutor()  # 默认是当前计算机cpu的个数
    
    '''
    尺子中创建的进程/线程创建一次就不会再创建了,
    至始至终用的都是最初的那几个,这样的话节省了反复开辟进程/线程的资源
    '''
    def task(n):
        print(n,os.getpid())  # 查看当前进程号
        time.sleep(2)
        return n*2
    
    def call_back(n):
        print('拿到了异步提交的任务的返回结果:',n.result())
    
    '''
    提交任务的方式
        同步:提交任务之后,原地等待任务的返回结果,期间不做任何事
        异步:提交任务之后,不等待任务的返回结果,直接指向下一步
    '''
    # pool.submit(task,1)  # 朝线程池中提交任务 ,异步提交
    # print('主')
    
    '''
    异步回调机制:当异步提交的任务有返回结果之后,会自动出发回调函数的执行
    '''
    # if __name__ == '__main__':
    #     t_list = []
    #     for i in range(5):
    #         # 提交任务的时候,绑定一个回调函数,一旦该任务有结果,立刻执行对于的回调函数
    #         res = pool.submit(task,i).add_done_callback(call_back)
    #         # print(res.result())  # 原地等待任务的返回结果
    #         t_list.append(res)
    # #
    #     # pool.shutdown()  # 关闭池子,等待池子中所有的任务执行完毕之后,才会往下运行代码
    #     # print(t_list)
    #     # for p in t_list:
    #     #     print('>>>:',p.result())
    
    
    ### 最终版本
    if __name__ == '__main__':
        for i in range(5):
            res = pool.submit(task,i).add_done_callback(call_back)
    案例

    二、协程

      完全是程序员自己想出来的名词,单线程下实现并发(并发:切换+保存状态)

        进程、线程、协程之间区别:

        进程:资源单位

        线程:执行单位

        协程:单线程下实现并发

    '''
    gevent模块
    '''
    
    from gevent import monkey;monkey.patch_all()  # 由于该模块经常被使用,建议写成一行
    from gevent import spawn
    import time
    '''
    注意gevent模块没办法自动识别time.sleep等io情况
    需要手动再配置一个参数
    '''
    
    def heng():
        print("")
        time.sleep(2)
        print('')
    
    def ha():
        print('')
        time.sleep(3)
        print('')
    
    def heiheihei():
        print('嘿嘿嘿')
        time.sleep(5)
        print('嘿嘿嘿')
    
    start = time.time()
    g1 = spawn(heng)
    g2 = spawn(ha)  # spawn 会检测所有的任务
    g3 = spawn(heiheihei)
    g1.join()
    g2.join()
    g3.join()
    print(time.time()-start)

    三、IO模型:

    阻塞io

    非阻塞io

    多路复用io

    异步io

      

      

  • 相关阅读:
    docker常用命令
    2020/10/10,饮食男女-对教条主义的补充和现实的摸索
    2020/08/24,约束力
    2020/08/21,迷茫的时候就去工作
    2020/08/21,神秘和平易近人
    2020/08/21,圣人和教条
    2020/07/21,翡翠梦境
    2020/10/10,生活不是阶段式跳跃的,是螺旋式的。
    2020/07/23,再论point,way,moment,time
    2020/07/13,旅游的意义是什么
  • 原文地址:https://www.cnblogs.com/xiaowangba9494/p/11359292.html
Copyright © 2011-2022 走看看