concurrent.futures 是 Python 从 3.2 开始引入的一个并发编程标准库,提供高级接口,用于执行异步任务。它基于线程(ThreadPoolExecutor)或进程(ProcessPoolExecutor)池,通过统一的 API 管理多个任务的提交与执行,显著简化了并发编程的复杂。

与传统的 threading 和 multiprocessing 相比,concurrent.futures 更适合管理大量独立任务,如 I/O 密集型请求或 CPU 密集型计算。

常见应用场景:

(1)并发下载多个网页或文件(I/O 密集)。

(2)并行处理大量图像、数据块(CPU 密集)。

(3)批量提交任务并等待结果返回。

(4)实现任务超时、取消、优先级等机制。

(5)用于 GUI 程序或服务器中进行后台任务处理。

  ◆  ◆

核心概念

1、Executor(执行器)

concurrent.futures.Executor 是一个抽象基类,定义了任务提交和生命周期管理的接口。

不能直接实例化,通常使用它的两个子类:

ThreadPoolExecutor:基于线程,适用于 I/O 密集型任务。

ProcessPoolExecutor:基于进程,适用于 CPU 密集型任务。

2、Future(未来对象)

表示一个异步执行的任务。

Future 对象可用于:查询任务是否完成、获取任务结果(阻塞或超时)、取消任务以及注册回调函数,等等。

  ◆  ◆

应用举例

例 1:使用线程池并发执行 I/O 密集型任务

from concurrent.futures import ThreadPoolExecutorimport time
def download(url):    print(f"开始下载 {url}")    time.sleep(2)  # 模拟 I/O 延迟    return f"{url} 下载完成"
urls = ["url1", "url2", "url3"]
with ThreadPoolExecutor(max_workers=3) as executor:    results = executor.map(download, urls)
for result in results:    print(result)

例 2:使用进程池进行并行计算

from concurrent.futures import ProcessPoolExecutor
# 迭代版本的 Fibonacci,避免栈溢出def fib(n):    a, b = 0, 1    for _ in range(n):        a, b = b, a + b    return a
if __name__ == "__main__":  # 多进程必须加此保护    with ProcessPoolExecutor() as executor:        results = executor.map(fib, [20, 25, 30])    for r in results:        print(r)

例 3:使用 submit + Future 获取任务状态

from concurrent.futures import ThreadPoolExecutorimport time
def task(n):    time.sleep(n)    return f"任务 {n} 秒完成"
executor = ThreadPoolExecutor()future = executor.submit(task, 3)
print("等待任务完成…")print(future.result())  # 会阻塞直到任务完成

例 4:使用 as_completed 获取最快完成的任务

from concurrent.futures import ThreadPoolExecutor, as_completedimport time
def work(x):    time.sleep(x)    return f"{x}秒任务完成"
with ThreadPoolExecutor(max_workers=3) as executor:    futures = [executor.submit(work, i) for i in [3, 1, 2]]    for f in as_completed(futures):        print(f.result())

例 5:设置任务超时与取消

from concurrent.futures import ThreadPoolExecutor, TimeoutErrorimport time
def long_task():    time.sleep(5)    return "完成"
executor = ThreadPoolExecutor()future = executor.submit(long_task)
try:    result = future.result(timeout=2)except TimeoutError:    print("任务超时,准备取消…")    future.cancel()

  ◆  ◆

常用函数速览

Executor.map(func, *iterables, timeout=None, chunksize=1)

将函数应用于每个迭代项,返回结果迭代器(阻塞等待全部完成)。

参数:

func:要并发执行的函数

*iterables:输入参数迭代器

timeout:超时设置

chunksize:用于 ProcessPoolExecutor 时的数据块大小

返回:生成结果的迭代器

Executor.shutdown(wait=True, cancel_futures=False)

关闭线程/进程池,释放资源。

参数:

wait:是否等待任务完成

cancel_futures:是否取消尚未开始的任务(Python 3.9+)

返回:无

Executor.submit(fn, *args, **kwargs)

提交单个任务,异步执行,返回一个 Future 对象。

参数:

fn:要执行的函数

args, kwargs:传入函数的参数

返回:concurrent.futures.Future 对象

as_completed(fs, timeout=None)

返回一个迭代器,每当某个 Future 完成即返回。

参数:

fs:Future 对象列表

timeout:最长等待时间

返回:已完成任务的 Future 对象迭代器

wait(fs, timeout=None, return_when=ALL_COMPLETED)

等待多个 Future 对象完成,返回两个集合:已完成和未完成的任务。

参数:

fs:Future 对象集合;

timeout:最长等待时间;

return_when:条件之一:FIRST_COMPLETED、FIRST_EXCEPTION

ALL_COMPLETED(默认)

返回:(done, not_done) 元组

  ◆  ◆

补充说明

1、ThreadPoolExecutor 适合处理网络、文件、数据库等 I/O 密集型任务。

2、ProcessPoolExecutor 适合处理大规模计算任务。

3、concurrent.futures 让多线程与多进程接口统一、使用简单,推荐在新项目中使用。

4、Python 3.9 后支持取消待执行任务(cancel_futures=True)。

5、任务执行时抛出的异常也会在 .result() 调用时被抛出,便于调试。

6、与 asyncio 不同,本库不基于事件循环,更适合传统并发场景。

图片

“点赞有美意,赞赏是鼓励”

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐