并发
Rust 用类型系统把数据竞争挡在编译期:所有权 保证可变 alias 唯一;跨线程共享常用 Arc + Mutex/RwLock 或 通道 std::sync::mpsc。Send 与 Sync(泛型与Trait)标记类型是否可在线程间传递与共享引用。
线程 std::thread
let h = std::thread::spawn(|| { /* 闭包 */ });
h.join().unwrap();- 闭包默认
move捕获以满足'static(线程可能活过当前栈帧):所捕获类型须为Send + 'static(常见约定)。 - 父子线程 panic:
join可拿到Err。
Send 与 Sync
| Trait | 大致含义 |
|---|---|
Send | 所有权可转移到另一线程 |
Sync | &T 可安全在多个线程间共享(T: Sync 等价于 &T: Send 的常用直觉) |
裸指针 *const T / *mut T 默认非 Send/Sync,unsafe 代码可手动 impl(责任在作者)。
共享状态:Arc + Mutex
use std::sync::{Arc, Mutex};
let data = Arc::new(Mutex::new(0));
let d = data.clone();
std::thread::spawn(move || {
*d.lock().unwrap() += 1;
});Arc:引用计数的不可变共享指针;需内部可变性时用Mutex<T>等。- 死锁:多把锁时注意加锁顺序;
try_lock可做非阻塞尝试。
通道 mpsc
多生产者、单消费者 FIFO 队列;消息类型 Send。
let (tx, rx) = std::sync::mpsc::channel();
tx.send(1).unwrap();
let v = rx.recv().unwrap();适合流水线与避免共享可变状态。
异步(简述)
async fn 与 await 由运行时(如 tokio)轮询 Future;与 OS 线程模型不同,属于协作式调度。选型见项目文档;与 Send、'static 在跨任务 .spawn 时仍有约束。
与借用 / 生命周期
跨线程闭包不能直接借环境栈上的短生命周期引用,除非生命周期可证明安全(少见);通常 move + Arc 或 通道拷贝/移动所有权。