2. 并发与异步编程

Python 提供了多种并发编程模型,理解它们的特点和适用场景是写出高效程序的关键。

2.6. 并发 vs 并行

        graph TD
    A[并发编程] --> B[并发 Concurrency]
    A --> C[并行 Parallelism]
    B --> D[单核心<br>任务交替执行]
    C --> E[多核心<br>任务同时执行]
    D --> F[线程/协程]
    E --> G[多进程]
    

2.6.1. 概念区分

特性

并发 (Concurrency)

并行 (Parallelism)

定义

同时处理多个任务

同时执行多个任务

CPU

可以是单核

需要多核

Python 实现

线程、协程

多进程

适用场景

I/O 密集型

CPU 密集型

2.6.2. Python 并发模型选择

# 场景分析

# 1. I/O 密集型(网络请求、文件操作、数据库查询)
# 推荐:asyncio(首选)或 threading
# 原因:等待 I/O 时可以切换到其他任务

# 2. CPU 密集型(数值计算、图像处理、数据分析)
# 推荐:multiprocessing 或 concurrent.futures.ProcessPoolExecutor
# 原因:绕过 GIL,利用多核

# 3. 混合型
# 推荐:组合使用,或使用 Ray、Dask 等框架

2.7. 快速对比

import time
import threading
import multiprocessing
import asyncio

def io_bound_task():
    """I/O 密集型任务"""
    time.sleep(1)
    return "done"

def cpu_bound_task(n):
    """CPU 密集型任务"""
    total = 0
    for i in range(n):
        total += i * i
    return total

async def async_io_task():
    """异步 I/O 任务"""
    await asyncio.sleep(1)
    return "done"

# 测试代码...

2.7.1. 性能对比(10 个 I/O 任务)

方式

时间

说明

串行

~10s

一个接一个

多线程

~1s

并发执行

多进程

~1s

并行执行(资源开销大)

asyncio

~1s

并发执行(最轻量)

2.7.2. 性能对比(CPU 密集型任务)

方式

时间

说明

串行

基准

-

多线程

≈ 基准

GIL 限制

多进程

基准/核心数

真正并行

asyncio

≈ 基准

不适合 CPU 密集

2.8. 本章重点

GIL 深度解析

理解全局解释器锁的原理和影响,知道何时它是问题,何时不是。

多线程编程

线程同步、锁、条件变量,以及如何避免死锁和竞态条件。

多进程编程

进程间通信、共享状态、进程池的正确使用。

asyncio 异步编程

协程、事件循环、异步上下文,构建高性能异步应用。

2.9. 选型指南

        graph TD
    A[任务类型?] --> B{I/O 密集型}
    A --> C{CPU 密集型}
    A --> D{混合型}
    
    B --> E{需要高并发?}
    E -->|是| F[asyncio]
    E -->|否| G[threading]
    
    C --> H{可以用 NumPy?}
    H -->|是| I[NumPy 已释放 GIL]
    H -->|否| J[multiprocessing]
    
    D --> K[分离 I/O 和 CPU<br>分别处理]