- 共享可变变量未加同步机制
fn main() {
let mut data = 0;
std::thread::spawn(|| {
data += 1;
}).join().unwrap();
data += 2;
}
- 解释:这里声明了一个可变变量
data
,多个线程(这里虽然只启动了一个线程,但如果有多个线程类似操作也会出现问题)可以访问并修改它。Rust默认变量在多线程间访问是不安全的,由于没有同步机制(如锁),不同线程对data
的读写操作可能会交错,导致结果不可预测,这就是竞态条件。
- 使用
Rc
(引用计数)在多线程间共享数据
use std::rc::Rc;
fn main() {
let shared_data = Rc::new(0);
let cloned_data = Rc::clone(&shared_data);
std::thread::spawn(move || {
let _ = cloned_data;
}).join().unwrap();
let _ = shared_data;
}
- 解释:
Rc
本身不是线程安全的,它通过引用计数来管理内存。在多线程环境下,多个线程同时操作Rc
的引用计数可能会导致计数错乱,进而可能出现内存释放问题或数据访问冲突,引发竞态条件。
- 未正确使用
Mutex
(互斥锁)
use std::sync::{Mutex, Arc};
fn main() {
let data = Arc::new(Mutex::new(0));
let cloned_data = Arc::clone(&data);
std::thread::spawn(move || {
let mut guard = cloned_data.lock().unwrap();
*guard += 1;
}).join().unwrap();
let mut guard = data.lock().unwrap();
*guard += 2;
}
- 解释:虽然使用了
Mutex
来保护共享数据,但如果在实际应用中,没有正确处理MutexGuard
(比如提前释放锁、在锁未获取成功时继续操作共享数据等),就可能导致多个线程同时访问共享数据,引发竞态条件。例如,如果在获取锁失败时没有合适的重试逻辑或处理方式,其他线程可能在该线程认为已获取锁时也获取锁并操作数据。