• 进程池,线程池,协程


    进程池、线程池、协程

    池子有什么作用

    在池子创建的时候就将设置的数量创建出来。之后所有的操作都由池子里的进程/线程完成。

    当并发的任务数量远远大于计算机所能承受的范围,限制我进程数或线程数,从保证服务器运行。

    concurrent.future模块

    • concurrent.future模块封装了线程池与进程池
    • ProcessPoolExecutor(max_works)对于进程池如果不写max_works:默认的是处理器个数
    • ThreadPoolExecutor(max_works)对于线程池如果不写max_works:默认的是处理器个数*5

    常用方法

    • result :获得回调函数返回的值
    • submit :相当于apply_async方法
    • shutdown :相当于close+join方法
    • add_done_callback :为当前任务绑定一个回调函数

    进程池

    from  concurrent.futures import ProcessPoolExecutor
    import time,random
    def task(n):
        for i in range(100):
            n += i   # 计算密集型的,一般用进程,可以充分利用多核优势
        return n**2
    if __name__ == '__main__':
        start = time.time()
        p = ProcessPoolExecutor()
        for i in range(10):
            obj = p.submit(task,i).result()  # 等同于apply同步方法
            print(obj)
        p.shutdown()
        print(time.time() - start)
    ##############################
    # 结果:
    0.23636794090270996
    

    线程池

    from  concurrent.futures import ProcessPoolExecutor
    import time
    def task(n):
        time.sleep(3)   # IO密集型的,一般用线程
        return n**2
    if __name__ == '__main__':
        start = time.time()
        p = ProcessPoolExecutor()
        for i in range(10):
            obj = p.submit(task,i).result()  # 等同于apply同步方法
        p.shutdown()
        print(time.time() - start)
    ##############################
    # 结果:
    30.011648893356323
    

    使用回调函数

    进程池
    from  concurrent.futures import ProcessPoolExecutor
    import time,random
    def parse(future)
    	print(future.result())
        
    def task(n):
        for i in range(100):
            n += i   # 计算密集型的,一般用进程,可以充分利用多核优势
        return n**2
    
    if __name__ == '__main__':
        start = time.time()
        p = ProcessPoolExecutor()
        for i in range(10):
            obj = p.submit(task,i)  # 等同于apply_async同步方法
            obj.add_done_callback(parse)  # 绑定函数,当当前任务结束时调用绑定方法
        p.shutdown()
        print(time.time() - start)
    ##############################
    # 结果:
    0.2219409942626953
    
    线程池
    from  concurrent.futures import ProcessPoolExecutor
    import time
    def parse(future):
    	print(future.result())
    def task(n):
        time.sleep(3)   # IO密集型的,一般用线程
        return n**2
    if __name__ == '__main__':
        start = time.time()
        p = ProcessPoolExecutor()
        for i in range(10):
            obj = p.submit(task,i)  # 等同于apply同步方法
            obj.add_done_callback(parse)
        p.shutdown()
        print(time.time() - start)
    ##############################
    # 结果:
    9.223718166351318
    

    协程

    • 单线程下实现并发(IO密集型提高效率)

    • 并发的本质:切换+保存状态

    • 降低单个线程的IO时间

    简单的协程
    from gevent import monkey
    monkey.patch_all() #实现捕获非gevent的io
    import gevent
    
    import time
    def eat():
        print('eat 1')
        time.sleep(2)
        print('eat 2')
    def play():
        print('开始运算')
        for i in range(1,10000):
            while i:
                i -= 1
        print('结束运算')
    
    start = time.time()
    # play()
    # eat()
    # 串行执行需要4.417968988418579
    g1 = gevent.spawn(eat)
    g2 = gevent.spawn(play)
    g1.join()
    g2.join()
    end = time.time()
    print(end-start)  # 2.4216597080230713
    
  • 相关阅读:
    BZOJ 3626: [LNOI2014]LCA(树链剖分+离线处理)
    python备用
    STL的使用。。备忘
    DP专题
    任务
    hdu 网络流题集
    hdu KM匹配题集
    hdu 差分约束题集
    hdu 2sat题集
    Codeforces Round #261 (Div. 2)
  • 原文地址:https://www.cnblogs.com/Gredae/p/11570318.html
Copyright © 2020-2023  润新知