07_线程池
1.为什么用线程池
1.启动一个新线程的消耗较高且涉及与操作系统的交互,尤其是程序中需要创建大量生存期很短暂的线程,而使用线程池可以很好地提升性能
2.线程池则是创建指定线程数量等待执行事件,当该事件执行结束后该线程并不会死亡,而是回到线程池中变成空闲状态等待执行下一个事件
3.当系统中包含有大量的并发线程时,会导致系统性能急剧下降甚至导致解释器崩溃,而使用线程池可以有效地控制系统中并发线程的数量
2.线程池的使用步骤
1.threadpool 模块实现线程池不推荐继续使用,此处推荐是用 concurrent.futures 模块中的 ThreadPoolExecutor 类实现线程池
2.调用 ThreadPoolExecutor 类的构造器创建一个线程池,定义一个普通函数作为线程任务
3.调用 ThreadPoolExecutor 对象的 submit() 方法来提交线程任务,调用 ThreadPoolExecutor 对象的 shutdown() 方法来关闭线程池
3.语法概述
from concurrent.futures import ThreadPoolExecutor thread_pool = ThreadPoolExecutor(max_workers=5) # 创建指定进程数量进程池并返回进程池对象 future = thread_pool.submit(fn, *args, **kwargs) # 将fn函数提交给线程池,并返回一个 future 对象 参数: *args 代表传给 fn 函数的参数 *kwargs 代表以关键字参数的形式为 fn 函数传入参数 # 该函数类似于内建函数 map(func, *iterables) 只是该函数将会启动多个线程,以异步方式立即对 iterables 执行 map 处理 thread_pool.map(func, *iterables, timeout=None, chunksize=1) # 提交多个任务给池中,等效for + submit thread_pool.shutdown(wait=True) # 等待池内所有任务执行完毕后关闭线程池 future.cancel() # 取消该future代表的线程任务,如果该任务正在执行不可取消则该方法返回False,否则程序会取消该任务并返回True future.cancelled() # 返回future代表的线程任务是否被成功取消 future.running() # 如果该future代表的线程任务正在执行不可被取消,该方法返回True future.done() # 如果该funture代表的线程任务被成功取消或执行完成,则该方法返回True future.result(timeout=None) # 获取该future代表的线程任务最后返回的结果,如果future代表的线程任务还未完成该方法将会阻塞当前线程 参数: timeout 指定最多阻塞等待多少秒 future.exception(timeout=None) # 获取该future代表的线程任务所引发的异常,如果该任务成功完成没有异常则该方法返回None future.add_done_callback(fn) # 为该future代表的线程任务注册一个回调函数,当该任务成功完成时程序会自动触发该fn函数