数据竞争与竞争条件
安全Rust保证了不存在数据竞争。数据竞争指的是:
- 两个或两个以上的线程并发地访问同一块内存
- 其中一个线程做写操作
- 其中一个线程是非同步(unsynchronized)的
但是Rust并不会避免一般竞争条件。
所以,安全Rust出现死锁,或者因为不正确的同步而做出一些奇怪的行为,这些都是可以接受的。显然这样的程序并不是最理想的程序,但Rust也只能帮你到这了。而且,竞争条件自己不能违反Rust的内存安全性。只有配合上其他的非安全代码,竞争条件才有可能破坏内存安全。比如:
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
let idx = Arc::new(AtomicUsize::new(0));
// move获得other_idx的所有权,将它移入线程
thread::spawn(move || {
// 可以改变idx,因为它的值是一个原子,不会引起数据竞争
});
if idx.load(Ordering::SeqCst) < data.len() {
unsafe {
// 在边界检查之后读取idx的值是不正确的,因为它有可能已经改变了。
// 这是一个竞争条件,而且十分危险,因为我们要使用的get_unchecked是非安全的。
println!("{}", data.get_unchecked(idx.load(Ordering::SeqCst)));