ThreadPoolExecutor 和 as_completed 是 Python 标准库 concurrent.futures 模块中的两个重要组件,用于实现多线程并发编程。以下是它们的详细介绍和使用示例:
ThreadPoolExecutor
ThreadPoolExecutor 是一个线程池执行器,用于管理线程的创建和执行。它允许你将任务提交到线程池中,而无需手动创建和管理线程。线程池可以复用线程,从而提高程序的性能和资源利用率。
基本用法
from concurrent.futures import ThreadPoolExecutor
# 定义一个任务函数
def task(n):
print(f"Task {n} is running on thread {threading.current_thread().name}")
time.sleep(2)
return f"Task {n} completed"
# 创建线程池执行器
with ThreadPoolExecutor(max_workers=3) as executor:
# 提交任务到线程池
futures = [executor.submit(task, i) for i in range(5)]
# 获取任务结果
for future in futures:
print(future.result())
参数说明
max_workers:指定线程池中最大线程数。如果为None,则默认值为min(32, os.cpu_count() + 4)。
as_completed
as_completed 是一个函数,用于从 Future 对象的集合中获取已经完成的任务。它返回一个迭代器,按任务完成的顺序yield每个 Future 对象。
基本用法
from concurrent.futures import ThreadPoolExecutor, as_completed
# 定义一个任务函数
def task(n):
print(f"Task {n} is running")
time.sleep(n)
return f"Task {n} completed"
# 创建线程池执行器
with ThreadPoolExecutor(max_workers=2) as executor:
# 提交任务到线程池
futures = [executor.submit(task, i) for i in [3, 1, 2]]
# 按任务完成顺序获取结果
for future in as_completed(futures):
print(future.result())
示例:结合使用 ThreadPoolExecutor 和 as_completed
以下是一个更复杂的示例,展示了如何结合使用 ThreadPoolExecutor 和 as_completed 来处理多个任务,并处理异常情况:
from concurrent.futures import ThreadPoolExecutor, as_completed
import threading
import time
import random
# 定义一个任务函数
def task(n):
print(f"Task {n} is running on thread {threading.current_thread().name}")
time.sleep(random.randint(1, 3))
if n == 2:
raise Exception(f"Task {n} failed")
return f"Task {n} completed"
# 创建线程池执行器
with ThreadPoolExecutor(max_workers=3) as executor:
# 提交任务到线程池
futures = [executor.submit(task, i) for i in range(5)]
# 按任务完成顺序获取结果
results = []
for future in as_completed(futures):
try:
result = future.result()
results.append(result)
print(result)
except Exception as e:
print(f"Task failed with exception: {e}")
print("All tasks completed:", results)
适用场景
- I/O 密集型任务:当任务涉及大量的 I/O 操作(如文件读写、网络请求)时,使用线程池可以提高程序的性能,因为线程在等待 I/O 操作完成时可以被其他任务复用。
- 并发执行任务:当需要同时执行多个任务,并且希望按任务完成的顺序处理结果时,
as_completed非常有用。
注意事项
- 线程安全:在多线程环境中,需要注意线程安全问题,避免数据竞争和共享资源的冲突。
- 任务数量:合理设置线程池的大小,避免创建过多的线程导致资源耗尽。
- 异常处理:在任务中可能会抛出异常,需要在主线程中捕获并处理这些异常。

1485

被折叠的 条评论
为什么被折叠?



