ThreadPoolExecutor是Python标准库concurrent.futures
中的一个类,用于创建和管理线程池。它简化了多线程编程,通过复用线程减少资源开销,适合处理I/O密集型任务。
构造函数参数说明:
max_workers
:线程池中最大线程数(默认值为CPU核心数*5)。thread_name_prefix
:线程名称前缀(Python 3.6+支持)。initializer
:线程初始化时的可调用对象(Python 3.7+支持)。示例代码:
from concurrent.futures import ThreadPoolExecutor
with ThreadPoolExecutor(max_workers=4) as executor:
# 任务提交代码
Future
对象。fn
(函数)、*args
(位置参数)、**kwargs
(关键字参数)。示例代码:
def task(name):
return f"Hello, {name}"
with ThreadPoolExecutor() as executor:
future = executor.submit(task, "World")
print(future.result()) # 输出:Hello, World
fn
(函数)、*iterables
(可迭代参数)。示例代码:
def square(x):
return x * x
with ThreadPoolExecutor() as executor:
results = executor.map(square, [1, 2, 3])
print(list(results)) # 输出:[1, 4, 9]
submit()
和 map()
是 Python 并发编程中常用的两种方法,通常与 concurrent.futures
模块的 ThreadPoolExecutor
或 ProcessPoolExecutor
一起使用。它们的主要区别在于使用场景和返回值。
submit()
用于提交单个可调用对象(如函数)到线程池或进程池,并立即返回一个 Future
对象。from concurrent.futures import ThreadPoolExecutor
def task(n):
return n * n
with ThreadPoolExecutor() as executor:
future = executor.submit(task, 5)
print(future.result()) # 输出 25
map()
用于提交一组可调用对象(相同函数)和参数列表,返回一个迭代器。from concurrent.futures import ThreadPoolExecutor
def task(n):
return n * n
with ThreadPoolExecutor() as executor:
results = executor.map(task, [1, 2, 3, 4])
for result in results:
print(result) # 输出 1, 4, 9, 16
submit()
返回 Future
对象,map()
返回结果迭代器。submit()
灵活支持不同任务,map()
适用于相同任务的批量处理。map()
保持输入顺序,submit()
需要手动管理 Future
对象。result(timeout=None)
:阻塞获取结果,超时抛出TimeoutError
。done()
:判断任务是否完成。add_done_callback(fn)
:添加回调函数(任务完成后自动调用)。示例代码:
def pow(a , b):
return a * b
def callback(future):
print(f"Callback result: {future.result()}")
with ThreadPoolExecutor() as executor:
future = executor.submit(pow, 2, 3)
future.add_done_callback(callback) # 输出:Callback result: 6
Future.exception()
捕获任务中的异常。with
语句自动关闭线程池。示例代码(异常处理):
def faulty_task():
raise ValueError("Oops")
with ThreadPoolExecutor() as executor:
future = executor.submit(faulty_task)
if future.exception():
print(f"Error: {future.exception()}")
该代码展示了如何用 ThreadPoolExecutor
提交一个会抛出异常的任务,并通过 Future
对象捕获并处理异常。
定义了一个函数 faulty_task()
,其中主动抛出 ValueError("Oops")
异常。
使用 ThreadPoolExecutor
上下文管理器创建线程池,并通过 submit()
方法提交任务。返回的 Future
对象 future
可用于查询任务状态。
future.exception()
检查任务是否抛出异常,若有异常则返回异常对象,否则返回 None
。
if future.exception():
判断任务是否发生异常,若发生则打印错误信息。
这种方式适合在任务结束后检查异常,而非实时捕获。若需实时处理,可在任务函数内部用 try-except
。
直接调用 future.exception()
会阻塞直到任务完成。若任务未完成,可能造成主线程等待。
建议结合 future.done()
检查任务状态,或使用 concurrent.futures.wait()
管理多个任务。
def faulty_task():
try:
raise ValueError("Oops")
except ValueError as e:
print(f"Task error: {e}")
raise # 重新抛出以便 future.exception() 捕获
with ThreadPoolExecutor() as executor:
future = executor.submit(faulty_task)
if future.done() and future.exception():
print(f"Error caught: {future.exception()}")
这种写法明确了异常处理层次,既在任务内部处理,又允许外部监控。