Python 提供了多种并发工具,让程序可以在等待 I/O 时处理其他任务,或通过多进程利用多个 CPU 核心。本文介绍 threadingmultiprocessingasyncioconcurrent.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 库提供了异步编程的能力,允许你编写单线程的并发代码。通过使用 asyncawait 关键字,你可以在不阻塞主线程的情况下执行多个操作。

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 中的并发编程。