Python线程池的使用
在 Python 中,concurrent.futures 模块提供了一个简单易用的线程池接口,用于管理和使用线程池。以下是线程池的常见用法及示例:
1. 基本用法
ThreadPoolExecutor 是用于线程池管理的主要类。它允许你方便地执行并发任务。
示例:基本使用
from concurrent.futures import ThreadPoolExecutor
import time
def task(name):
print(f"Task {name} is running")
time.sleep(2)
print(f"Task {name} is done")
return f"Result of {name}"
# 创建线程池
with ThreadPoolExecutor(max_workers=3) as executor:
# 提交任务
future1 = executor.submit(task, "A")
future2 = executor.submit(task, "B")
future3 = executor.submit(task, "C")
# 获取结果
print(future1.result())
print(future2.result())
print(future3.result())
2. 提交多个任务
使用 map 提交一组任务,类似于内置的 map 函数,但支持并发。
示例:使用 map 方法
from concurrent.futures import ThreadPoolExecutor
import time
def task(n):
time.sleep(1)
return n * n
# 创建线程池
with ThreadPoolExecutor(max_workers=3) as executor:
# 提交任务
results = executor.map(task, range(5)) # 提交 0, 1, 2, 3, 4 的任务
# 打印结果
for result in results:
print(result)
3. 异步获取结果
使用 as_completed 方法可以在任务完成后逐个处理结果。
示例:任务完成后逐个获取
from concurrent.futures import ThreadPoolExecutor, as_completed
import time
def task(n):
time.sleep(n)
return f"Task with sleep {n}s done"
# 创建线程池
with ThreadPoolExecutor(max_workers=3) as executor:
futures = [executor.submit(task, i) for i in range(1, 6)] # 提交 1-5 的任务
for future in as_completed(futures):
print(future.result())
4. 捕获异常
在任务执行过程中,可能会发生异常。通过 future.exception() 方法可以捕获。
示例:捕获任务中的异常
from concurrent.futures import ThreadPoolExecutor
def task(n):
if n == 2:
raise ValueError("An error occurred in task")
return n * n
with ThreadPoolExecutor(max_workers=3) as executor:
futures = [executor.submit(task, i) for i in range(5)]
for future in futures:
try:
print(future.result())
except Exception as e:
print(f"Exception: {e}")
5. 自定义线程数
max_workers 参数控制线程池中同时执行的最大线程数。
from concurrent.futures import ThreadPoolExecutor
import time
def task(n):
time.sleep(1)
print(f"Task {n} completed")
return n
with ThreadPoolExecutor(max_workers=2) as executor: # 最多同时运行 2 个线程
executor.map(task, range(5))
6. 常见注意事项
- I/O 密集型任务:适合使用线程池,因为线程池允许并发 I/O 操作。
- CPU 密集型任务:考虑使用进程池(
ProcessPoolExecutor),因为 Python 的 GIL 会限制线程的并发性能。 - 线程安全:注意在线程间共享数据时的同步问题,可以使用
threading.Lock等工具。
希望这些内容对你有所帮助!