zoukankan      html  css  js  c++  java
  • 线程池&进程池

    线程池&进程池

    池子解决什么问题?

    1.创建/销毁线程伴随着系统开销,如果过于频繁会影响系统运行效率
    2.线程并发数量过多,抢占系统资源,从而导致系统阻塞甚至死机
    3.能够刚好的控制和管理池子里面的线程和进程

    concurrent.futures模块提供了高度封装的异步调用接口

    ThreadPoolExecutor:线程池,提供异步调用

    ProcessPoolExecutor:进程池,提供异步调用

    常用方法

    submit(fn, *args, **kwargs):异步提交任务

    map(func, *iterables, timeout=None, chunksize=1):取代for循环submit的操作

    shutdown(wait=True):相当于进程池的pool.close()+pool.join()操作

    ​ wait=True,等待池内所有任务执行完毕回收完资源后才继续

    ​ wait=False,立即返回,并不会等待池内的任务执行完毕

    ​ 但不管wait参数为何值,整个程序都会等到所有任务执行完毕

    ​ submit和map必须在shutdown之前

    result(timeout=None):取得结果

    add_done_callback(fn):回调函数

    done():判断某一个线程是否完成

    cancle():取消某个任务

    例1 基本用法

    from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
    
    import os,time,random
    def work(i):
        print(f"work-{i}搬了一块砖头")
        time.sleep(1)
        return "zx"
    if __name__ == '__main__':
    
        executor=ProcessPoolExecutor(max_workers=3)
    
        #工人们
        futures=[]
    
        for i in range(11):
            future=executor.submit(work,i)
            futures.append(future)
    
        #线程池shutdown 关闭入口,等待所有任务结束
        executor.shutdown(True)
    
        #打印执行的结果
        for future in futures:
            print(future.result())
    
    work-0搬了一块砖头
    work-1搬了一块砖头
    work-2搬了一块砖头
    work-3搬了一块砖头
    work-4搬了一块砖头
    work-5搬了一块砖头
    work-6搬了一块砖头
    work-7搬了一块砖头
    work-8搬了一块砖头
    work-9搬了一块砖头
    work-10搬了一块砖头
    zx
    zx
    zx
    zx
    zx
    zx
    zx
    zx
    zx
    zx
    zx
    

    注意这样用会是不对的

    from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
    
    import os,time,random
    def work(i):
        print(f"work-{i}搬了一块砖头")
        time.sleep(1)
        return "zx"
    if __name__ == '__main__':
    
        executor=ProcessPoolExecutor(max_workers=3)
    
        for i in range(11):
            future=executor.submit(work,i)
            print(future.result())
    
    work-0搬了一块砖头
    zx
    work-1搬了一块砖头
    zx
    work-2搬了一块砖头
    zx
    work-3搬了一块砖头
    zx
    work-4搬了一块砖头
    zx
    work-5搬了一块砖头
    zx
    work-6搬了一块砖头
    zx
    work-7搬了一块砖头
    zx
    work-8搬了一块砖头
    zx
    work-9搬了一块砖头
    zx
    work-10搬了一块砖头
    zx
    

    例2 基础线程池加回调用法

    from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
    import threading
    import time,random
    
    def work(i):
        #获取当前线程对象
        thread = threading.current_thread()
        print(f"{thread.getName()}搬了第{i}块砖头")
        time.sleep(random.randint(1,3))
        return i
    
    def call_back(zx):
        res = zx.result()
        print(res)
    
    if __name__ == '__main__':
        #线程池为可装线程3个
        executor=ThreadPoolExecutor(max_workers=3)
    
        for i in range(11):
            executor.submit(work,i).add_done_callback(call_back)
    
    ThreadPoolExecutor-0_0搬了第0块砖头
    ThreadPoolExecutor-0_1搬了第1块砖头
    ThreadPoolExecutor-0_2搬了第2块砖头
    0
    ThreadPoolExecutor-0_0搬了第3块砖头
    2
    ThreadPoolExecutor-0_2搬了第4块砖头
    1
    ThreadPoolExecutor-0_1搬了第5块砖头
    3
    ThreadPoolExecutor-0_0搬了第6块砖头
    5
    ThreadPoolExecutor-0_1搬了第7块砖头
    4
    ThreadPoolExecutor-0_2搬了第8块砖头
    6
    ThreadPoolExecutor-0_0搬了第9块砖头
    9
    ThreadPoolExecutor-0_0搬了第10块砖头
    7
    8
    10
    

    例3 进程池加回调函数

    from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
    import time,random,os
    
    def work(i):
        #打印当前进程pid
        print(f"{os.getpid()}搬了第{i}块砖头")
        time.sleep(random.randint(1,3))
        return i
    
    def call_back(zx):
        res = zx.result()
        print(res)
    
    if __name__ == '__main__':
        #线程池为可装线程3个
        executor=ProcessPoolExecutor(max_workers=3)
    
        for i in range(11):
            executor.submit(work,i).add_done_callback(call_back)
    
    18696搬了第0块砖头
    22500搬了第1块砖头
    4172搬了第2块砖头
    22500搬了第3块砖头
    1
    22500搬了第4块砖头
    3
    18696搬了第5块砖头
    0
    4172搬了第6块砖头
    2
    22500搬了第7块砖头
    4
    18696搬了第8块砖头
    5
    18696搬了第9块砖头
    8
    4172搬了第10块砖头
    6
    7
    9
    10
    
  • 相关阅读:
    FZU 2112 并查集、欧拉通路
    HDU 5686 斐波那契数列、Java求大数
    Codeforces 675C Money Transfers 思维题
    HDU 5687 字典树插入查找删除
    HDU 1532 最大流模板题
    HDU 5384 字典树、AC自动机
    山科第三届校赛总结
    HDU 2222 AC自动机模板题
    HDU 3911 线段树区间合并、异或取反操作
    CodeForces 615B Longtail Hedgehog
  • 原文地址:https://www.cnblogs.com/zx125/p/11553186.html
Copyright © 2011-2022 走看看