concurrent.future模块

future 是 Python 中的一种异步编程工具,特别用于处理并发执行的任务。它是 concurrent.futures 模块的一部分,可以帮助你在多线程或多进程环境下异步地执行任务,并返回任务的结果。

在 Python 的异步编程中,Future 对象表示一个正在执行的任务,它还可以表示任务的结果、异常,或者任务是否完成。你可以使用 Future 来跟踪一个任务的状态,获取结果或处理异常。

官方文档:

  1. concurrent.futures 模块: https://docs.python.org/3/library/concurrent.futures.html
  2. Future 类: https://docs.python.org/3/library/concurrent.futures.html#future-objects

主要内容:

  1. concurrent.futures.Future 类: Future 是一个表示计算结果的占位符,通常与线程池或进程池一起使用。你可以把它看作一个将来完成的任务的“承诺”。 你可以查询 Future 对象的状态,例如任务是否已完成,结果是什么等。
  2. concurrent.futures 模块: 这个模块提供了高级的并发执行方法,可以轻松地执行多线程和多进程任务。

1. 创建 Future 对象

通常你不会直接创建 Future 对象,而是通过 Executor(线程池或进程池)来创建它们。Future 对象会由执行的任务自动生成。

示例:多线程任务执行

import concurrent.futures
import time

def task(n):
    print(f"Task {n} is running")
    time.sleep(2)
    return f"Task {n} finished"

# 使用 ThreadPoolExecutor 创建线程池
with concurrent.futures.ThreadPoolExecutor() as executor:
    # 提交任务并返回一个 Future 对象
    future = executor.submit(task, 1)

    # 获取结果,阻塞直到任务完成
    result = future.result()
    print(result)

2. Future 的常用方法

future.result()

  • 阻塞直到任务完成并返回结果。如果任务抛出异常,则会在调用 result() 时重新抛出。

future.done()

  • 返回一个布尔值,表示任务是否已经完成。

future.cancel()

  • 尝试取消任务。如果任务还没有开始执行,则可以取消它。如果任务已经开始执行,则无法取消。

future.exception()

  • 如果任务抛出异常,调用 exception() 可以获取异常。如果任务没有抛出异常,则返回 None。

future.add_done_callback()

  • 为 Future 对象添加一个回调函数,这个回调函数会在任务完成时被调用。

3. 示例:异步执行多个任务

import concurrent.futures

def task(n):
    return n * 2

# 使用 ThreadPoolExecutor 执行多个任务
with concurrent.futures.ThreadPoolExecutor() as executor:
    # 提交多个任务
    futures = [executor.submit(task, i) for i in range(5)]

    # 等待所有任务完成,并获取结果
    for future in concurrent.futures.as_completed(futures):
        print(future.result())

在这个示例中,我们同时提交了 5 个任务到线程池中,as_completed() 会返回一个迭代器,逐个返回已经完成的任务的结果。

4. concurrent.futures 中的 Executor

在使用 Future 对象时,通常与 Executor 类一起使用。Executor 提供了一个简单的接口来异步执行任务,有两种常用的执行器:

  • ThreadPoolExecutor:适用于 IO 密集型任务。
  • ProcessPoolExecutor:适用于 CPU 密集型任务。

示例:使用 ProcessPoolExecutor

import concurrent.futures

def compute_square(n):
    return n * n

# 使用 ProcessPoolExecutor 执行计算任务
with concurrent.futures.ProcessPoolExecutor() as executor:
    results = list(executor.map(compute_square, range(10)))

print(results)

5. 使用 Future 对象来执行回调

你还可以使用 Futureadd_done_callback 方法来指定任务完成后的回调函数。这在某些需要后处理的场景中非常有用。

import concurrent.futures

def task(n):
    return n * 2

def callback(future):
    print(f"Task finished with result: {future.result()}")

# 使用 ThreadPoolExecutor 执行任务并注册回调
with concurrent.futures.ThreadPoolExecutor() as executor:
    future = executor.submit(task, 5)
    future.add_done_callback(callback)

task(5) 完成后,callback 函数会被调用,并且输出结果 10

总结

  • Future 是用来表示一个将来完成的任务,可以通过 Executor 提交任务并获得 Future 对象。
  • 通过 Future 对象,你可以检查任务的状态、获取结果或者处理异常。
  • concurrent.futures 提供了多种方法来简化并发编程,例如 ThreadPoolExecutor 和 ProcessPoolExecutor,以及通过 Future 对象管理任务的生命周期。

futureconcurrent.futures 模块的结合使得并发编程变得更加简单和直观。


文章标签:

评论(0)