【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"})
执行结果
-------------------------------------------------------------------------------------
如果万事开头难 那请结局一定圆满 @ Phoenixy
-------------------------------------------------------------------------------------