Python线程池的使用

134 阅读2分钟

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 等工具。

希望这些内容对你有所帮助!