Linux 下 Rust 的并发模型概览
std::thread),二是基于 async/await 的协程式并发(由 Tokio/async-std 等运行时驱动)。前者贴近操作系统线程,后者通过 Future 与事件循环在少量线程上调度海量任务,适合 I/O 密集型 场景。Rust 以编译期类型系统保障并发安全,核心在于 Send/Sync 标记 trait 与所有权/借用规则,从语言层面避免数据竞争。线程模型与同步原语
std::thread::spawn 创建新线程,JoinHandle::join 等待回收;可用 thread::Builder 设置线程名、栈大小等。该模型是 1:1(一个 Rust 线程对应一个 OS 线程)。std::sync::mpsc),遵循“通过通信共享内存”,减少显式锁的使用。Arc<Mutex<T>> 或 Arc<RwLock<T>> 包装共享数据;Arc 提供原子引用计数,Mutex 保证独占访问,RwLock 允许多读单写。std::sync::atomic(如 AtomicUsize)进行无锁更新。Rc<T>/RefCell<T> 不是线程安全的(不实现 Send/Sync),跨线程共享请改用 Arc/Mutex 等。异步并发模型与运行时
async fn 返回 Future,.await 在等待时让出执行权而非阻塞线程;运行时的 Reactor/Executor/Timer 负责事件监听、任务调度与唤醒。#[tokio::main(flavor = "multi_thread", worker_threads = N)] 配置多线程调度,或用 current_thread 单线程模式;大量并发任务以少量线程承载,提高吞吐。tokio::sync::mpsc(异步有界通道,具备背压)、tokio::sync::Mutex(异步锁,需在 .await 上下文中使用)等组件协作。.await 处切换任务,长时间 CPU 计算会阻塞当前线程,应拆分或放入专用线程池。如何选择并发模型
| 场景 | 推荐模型 | 关键要点 |
|---|---|---|
| CPU 密集型(计算、压缩、编码) | 多线程 + std::thread/rayon |
利用多核并行;注意共享数据用 Arc<Mutex/RwLock>,避免锁竞争与伪共享 |
| I/O 密集型(网络、数据库、磁盘) | 异步 + Tokio/async-std | 少量线程承载大量任务;优先用异步 I/O 与异步锁/通道;避免阻塞调用 |
| 混合型 | 异步为主,计算 offload 到线程池 | 计算阶段 spawn_blocking 或专用 rayon 池,I/O 阶段用 async/await |
| 高吞吐短任务/大量连接 | 异步任务 + 工作窃取调度 | 任务粒度细、调度开销低;使用 tokio::spawn 与 JoinHandle 管理生命周期 |
常见陷阱与最佳实践
std::fs::read、thread::sleep)会阻塞运行时线程,改用 tokio::fs/tokio::time::sleep 等异步 API。tokio::sync::Mutex,同步代码用 std::sync::Mutex;切勿在 .await 点持有异步锁跨越 await。Arc 替代 Rc,用 Atomic*/Mutex/RwLock 管理共享可变状态。await 或 JoinHandle:未 await 的 spawn 任务可能被丢弃;未 join 可能导致资源提前释放或逻辑未完成。