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
    
  • 相关阅读:
    hive实现根据用户分组,按用户记录求上下两条记录的时间差
    国外互联网公司大数据技术架构研究
    Hadoop源码解析之 rpc通信 client到server通信
    一致性哈希与java实现
    spark 对hbase 操作
    Spark MLlib(下)--机器学习库SparkMLlib实战
    PHP源码进行加密(仅linux)
    有个问题需要将字符串(大数字)计算相加并转换成字符串,传递的参数是字符串。
    Js中Array 函数使用方法
    phpstorm配置xdebug调试
  • 原文地址:https://www.cnblogs.com/zx125/p/11553186.html
Copyright © 2011-2022 走看看