Python 提供了多种并发工具,让程序可以在等待 I/O 时处理其他任务,或通过多进程利用多个 CPU 核心。本文介绍 threading、multiprocessing、asyncio 和 concurrent.futures 的基本用法与适用场景。
1. 线程(Threading)
Python 的 threading 模块允许在同一个进程内创建多个线程。线程共享内存,适合网络请求、文件读写等 I/O 密集型任务,但共享状态也会带来竞态条件和死锁风险。在常见的 CPython 实现中,GIL 会限制多个线程同时执行 Python CPU 密集型代码,因此线程并不等同于 CPU 并行。
1.1 线程的基本使用
import threading
def print_numbers():
for i in range(5):
print(i)
# 创建线程
thread = threading.Thread(target=print_numbers)
thread.start()
thread.join()
2. 多进程(Multiprocessing)
为了绕过 Python 的全局解释器锁(GIL),multiprocessing 模块允许你创建多个进程。每个进程有自己的内存空间和 Python 解释器,因此可以实现真正的并行计算。
2.1 多进程的基本使用
from multiprocessing import Process
def print_numbers():
for i in range(5):
print(i)
# 创建进程
process = Process(target=print_numbers)
process.start()
process.join()
3. 异步编程(asyncio)
Python 的 asyncio 库提供了异步编程的能力,允许你编写单线程的并发代码。通过使用 async 和 await 关键字,你可以在不阻塞主线程的情况下执行多个操作。
3.1 异步编程的基本使用
import asyncio
async def print_numbers():
for i in range(5):
print(i)
await asyncio.sleep(1)
# 运行事件循环
asyncio.run(print_numbers())
4. 并发执行的高阶工具
Python 还提供了一些高阶工具来简化并发编程,如 concurrent.futures 模块,它提供了线程池和进程池的高阶接口。
4.1 使用线程池
from concurrent.futures import ThreadPoolExecutor
def perform_task(x):
return x * x
with ThreadPoolExecutor(max_workers=5) as executor:
results = list(executor.map(perform_task, range(5)))
4.2 使用进程池
from concurrent.futures import ProcessPoolExecutor
def perform_task(x):
return x * x
with ProcessPoolExecutor(max_workers=5) as executor:
results = list(executor.map(perform_task, range(5)))
5. 总结
Python 的并发工具解决的是不同问题:I/O 密集型任务通常适合线程或 asyncio,CPU 密集型任务通常适合多进程。选择之前应先判断瓶颈来自等待还是计算,再考虑共享状态、错误处理和任务取消等工程成本。
这篇文章基于 Python 官方说明文档中的并发执行部分,介绍了 Python 中实现并发执行的主要模块和工具,以及它们的使用示例。希望这能帮助你更好地理解和应用 Python 中的并发编程。