线程池&进程池的应用
坚持你所坚持的,你一定会成功!
一、为什么要使用线程池?
工作中需要对接口进行压测,想要并发读取文件中的url发送请求。起初使用的是线程,但是缺点是每次要创建一个新的线程,
二、ThreadPoolExecutor:
线程池的基类是 concurrent.futures 模块中的 Executor,Executor 提供了两个子类,即
ThreadPoolExecutor 和 ProcessPoolExecutor,其中 ThreadPoolExecutor
用于创建线程池,而 ProcessPoolExecutor 用于创建进程池。 Exectuor 提供了如下常用方法:submit(fn, *args, **kwargs):将 fn 函数提交给线程池。*args 代表传给 fn 函数的参数,*kwargs
代表以关键字参数的形式为 fn 函数传入参数。 map(func, *iterables, timeout=None,
chunksize=1):该函数类似于全局函数 map(func, *iterables),只是该函数将会启动多个线程,以异步方式立即对
iterables 执行 map 处理。 shutdown(wait=True):关闭线程池。 程序将 task
函数提交(submit)给线程池后,submit 方法会返回一个 Future 对象,Future
类主要用于获取线程任务函数的返回值。由于线程任务会在新线程中以异步方式执行,因此,线程执行的函数相当于一个“将来完成”的任务,所以Python 使用 Future 来代表。
Future 提供了如下方法:cancel():取消该 Future 代表的线程任务。如果该任务正在执行,不可取消,则该方法返回
False;否则,程序会取消该任务,并返回 True。cancelled():返回 Future 代表的线程任务是否被成功取消。
running():如果该 Future 代表的线程任务正在执行、不可被取消,该方法返回 True。
done():如果该 Funture 代表的线程任务被成功取消或执行完成,则该方法返回 True。
result(timeout=None):获取该 Future 代表的线程任务最后返回的结果。如果 Future
代表的线程任务还未完成,该方法将会阻塞当前线程,其中 timeout 参数指定最多阻塞多少秒。exception(timeout=None):获取该 Future 代表的线程任务所引发的异常。如果该任务成功完成,没有异常,则该方法返回
None。add_done_callback(fn):为该 Future 代表的线程任务注册一个“回调函数”,当该任务成功完成时,程序会自动触发该
fn 函数。代码如下(示例):
'''需求:并发读取txt中的URL地址'''
list_test = []
filename = "../../../xx.txt"
file = open(filename, "r")
# 列表推导式
list_test = [line.strip("\n") for line in file]
#创建线程池
pool=ThreadPoolExecutor(1)
fur_list=[]
url_list = [i for i in list_test]
for i in list_test:
#将request_post提交给线程池
future=pool.submit(request_post,i)
fur_list.append(future)
#关闭线程池
pool.shutdown(True)
for fu in fur_list:
#获取线程任务的返回结果
print(fu.result())