734 字
4 分钟
并发、并行、异步

核心定义
- 并发:多个任务在重叠时间段内执行(单核上下文切换)
- 并行:多个任务同时执行(需多核硬件支持)
- 异步:非阻塞任务调度,在等待I/O时释放线程执行其他任务 Rust 提供:
- 线程(
std::thread
)实现并发/并行 async/await
语法 + 运行时(如 Tokio)实现异步- 并行库(如
rayon
)简化数据并行处理
- 线程(
工作原理
并发/并行
通过 OS 线程或绿色线程(用户态线程)分割任务。线程间用通道(mpsc
)或锁(Mutex
)同步数据。
异步
- 异步函数返回
Future
(待执行任务) - 运行时(如 Tokio)调度
Future
,在 I/O 等待时挂起并执行其他任务 - I/O 就绪后唤醒任务继续执行
flowchart TD A[启动任务] --> B{执行模式} B -->|并发| C[单核切换执行 Task1/Task2] B -->|并行| D[多核同时执行 Task1+Task2] B -->|异步| E[Task1 等待I/O时执行 Task2] C & D & E --> F[完成]
关键点
- 线程安全:
Send
(可跨线程传递)+Sync
(可线程间共享)trait 保障安全 - 异步运行时:需外部库(如 Tokio)提供任务调度和I/O事件驱动
- 零成本抽象:Rust 异步无运行时开销(编译期生成状态机)
- 数据并行:
rayon
的par_iter()
自动拆分数据集到多核 - 同步原语:
Arc
/Mutex
共享数据,channel
跨线程通信
常见误区
- 混淆并发与并行:并发是编程模式,并行是执行方式
- 滥用线程:创建过多线程导致调度开销(异步更高效)
- 阻塞异步运行时:在异步任务中调用阻塞函数(如
std::net
) - 误用共享状态:未用
Mutex
导致数据竞争 - 忽略生命周期:跨线程传递引用需
'static
或Arc
应用场景
场景 | 解决方案 | 优势 |
---|---|---|
CPU密集型计算 | rayon 并行迭代器 | 自动利用多核,接近线性加速 |
高并发网络服务 | Tokio 异步运行时 | 单线程处理数千连接,低内存占用 |
实时数据处理管道 | 线程池 + 跨线程通道 | 解耦生产/消费,控制任务优先级 |
GUI事件循环 | async + 事件驱动(如 winit ) | 避免阻塞UI线程 |
批量I/O操作 | tokio::fs 异步文件操作 | 等待磁盘时释放线程执行其他任务 |
关联知识
- Future 系统:异步核心 trait,表示延迟计算
- Pin 与 Unpin:固定内存地址支持自引用结构
- 执行器(Executor):调度和运行
Future
(如 Tokio) - 反应器(Reactor):I/O 事件通知系统(如
mio
) - 工作窃取调度:运行时优化负载均衡(Tokio 默认)
- 原子操作:
AtomicBool
/AtomicUsize
实现无锁并发 - 线程局部存储:
thread_local!
实现线程私有数据
💡 黄金法则: CPU密集型 → 并行(
rayon
) I/O密集型 → 异步(tokio
/async-std
) 简单隔离任务 → 线程(std::thread
) 始终用RUST_LOG=info
监控运行时行为!