【Python】ThreadPoolExecutor 线程池

线程池在系统启动时即创建大量空闲的线程,程序只要将一个函数提交给线程池,线程池就会启动一个空闲的线程来执行它。

当该函数执行结束后,该线程并不会死亡,而是再次返回到线程池中变成空闲状态,等待执行下一个函数。

线程池的基类是 concurrent.futures 模块中的 Executor;Executor 提供了两个子类

  ThreadPoolExecutor 用于创建线程池,

  ProcessPoolExecutor 用于创建进程池。

常用方法:

  • submit(fn, *args, **kwargs):将 fn 函数提交给线程池。*args 代表传给 fn 函数的参数,*kwargs 代表以关键字参数的形式为 fn 函数传入参数。
  • map(func, *iterables, timeout=None, chunksize=1):该函数类似于全局函数 map(func, *iterables),只是该函数将会启动多个线程,以异步方式立即对 iterables 执行 map 处理。
  • shutdown(wait=True):关闭线程池。

 

基础语法

方法一:

def func(name, addr):
    tn = threading.currentThread().name
    logs.info("{} 姓名:{}, 住址:{}".format(tn, name, addr))
    time.sleep(3)
    return name


def threadPool_base(action, *args):
    # 创建一个最大容纳数量为2的线程池
    pool = ThreadPoolExecutor(max_workers=2)
    # for i in args:
    #     logs.info(i)
    # 通过submit提交执行的函数到线程池中
    all_task = [pool.submit(action, name=args[i].get("name"), addr=args[i].get("addr")) for i in range(len(args))]
    # 通过result来获取返回值
    result = [i.result() for i in all_task]
    # 线程池关闭
    pool.shutdown()
    logs.info("线程函数返回结果:{}".format(result))
    return result


if __name__ == "__main__":
    """run"""
    threadPool_base(func, {"name": "zhangsan", "addr": "beijing"})
    threadPool_base(func, {"name": "lisi", "addr": "shanghai"})
    threadPool_base(func, {"name": "wangwu", "addr": "shenzhen"})

 

执行结果

  

方法二:通过with管理线程,当线程池任务完成之后自动关闭线程池

def func(name, addr):
    tn = threading.currentThread().name
    logs.info("{} 姓名:{}, 住址:{}".format(tn, name, addr))
    time.sleep(3)
    return name


def threadPool_with(action, *args):
    all_task = []
    with ThreadPoolExecutor(max_workers=2) as pool:
        for i in range(len(args)):
            all_task.append(pool.submit(action, name=args[i].get("name"), addr=args[i].get("addr")))

        # 主线程等待所有子线程完成
        # wait(fs: 表示需要执行的序列, timeout: 等待的最大时间,如果超过这个时间即使线程未执行完成也将返回, return_when:表示wait返回结果的条件,默认为 ALL_COMPLETED 全部执行完成再返回,可选 FIRST_COMPLETED 第一个子线程完成)
        wait(all_task, return_when=FIRST_COMPLETED)
        logs.info("fist_结束")

        # 会阻塞线程,相当于return_when=ALL_COMPLETED 可与wait调整顺序
        result = [i.result() for i in all_task]
        logs.info(f"result:{result}")
        logs.info("全部结束")


if __name__ == "__main__":
    """run"""
    threadPool_with(func, {"name": "zhangsan", "addr": "beijing"}, {"name": "lisi", "addr": "beijing"}, {"name": "wangwu", "addr": "beijing"})

执行结果

 

posted @ 2023-04-06 21:31  Phoenixy  阅读(548)  评论(0编辑  收藏  举报