Python并发编程——线程池ThreadPoolExecutor

本篇文章为本人并发编程的学习记录,欢迎感兴趣的同学一起交流讨论!

目录

      • 1. 线程的生命周期
      • 2. 什么是线程池
      • 3. 线程池功能介绍
      • 4. ThreadPoolExecutor

1. 线程的生命周期

Python并发编程——线程池ThreadPoolExecutor_第1张图片

2. 什么是线程池

  • 线程池的来源:线程在新建的时候需要系统进行资源分配,而在终止的时候则需要进行资源的回收。大量功能相同线程的新建与终止需要消耗大量的系统资源,那么我们能不能像一种方法,将这些功能相同的线程进行统一管理呢,避免大量的新建与终止从而节省系统资源。
  • 线程池的具体操作方法:系统会维护一个任务清单,该清单中记录了等待程序执行的任务;同时维护一个线程池,池中保存了一定数量的线程。线程池中的线程在任务清单中接取任务并执行,在执行结束后并不终止而是重新接取任务。

3. 线程池功能介绍

  • 节省资源:线程池的使用减少了大量线程新建与终止的开销
  • 防御作用:避免因为建立太多的线程而导致的程序卡顿与终止的问题
  • 代码整洁:使用线程池相较于直接创建线程更加整洁
  • 适用场景:各线程执行时间较短;突发性大量请求。

4. ThreadPoolExecutor

  • 导入库
from concurrent.futures imoprt ThreadPoolExecutor
  • 定义方法
ThreadPoolExecutor(max_workers=...)  # 定义一个最大线程数为max_workers的线程池
  • 使用方法一——submit
with ThreadPoolExecutor() as pool:
	futures = []
	futures.append(pool.submit(target=func, args=(arg,)))
	futures.append(pool.submit(...)
	...
	for future in futures:
		print(future.result) 

# submit方法会返回一个future对象,该方法并不是在线程执行完毕后才返回的,而是在调用方法的时候即返回。
# future对象可以监测一个线程执行的状态
# .result()得到进程返回结果
# .done()判断进程是否执行结束
# ...
  • 使用方法二——map
with ThreadPoolExecutor(5) as pool:
	futures = pool.map(func, args)
	for future in futures:
		print(future.result())

# .map()使用起来十分方便,func为线程的target方法,而args则是每个线程所需的arg的list。map方法与python本身的map方法思路相同,即args中的每一个参数都执行相同的func操作。
# 需要注意的是,使用map方法进行线程池的操作,起返回值futures是按args的传入顺序排列的。(即使各个thread的执行结束顺序与之不同)
  • as_completed
from concurrent.futures import as_completed
with ThreadPoolExecutor(5) as pool:
	futures = pool.map(func, args)
	for future in as_completed(futures):
		print(future.result())

# as_completed(futures)是一个生成器,它会判断futures中的进程是否完成执行,如果执行完成则yeild这个future。
# 因此使用a s_completed包裹的futures其输出的顺序是不固定的,这在一些场合是有必要的。

你可能感兴趣的:(python,python,并发编程,线程池,多线程)