-1 multithreading unsafe vector rust raw-pointer
use std::sync::Arc;
use std::sync::atomic::{AtomicPtr, Ordering};
use std::thread;
fn main() {
let mut arr = vec![1,2,3];
let ptr = &mut arr as *mut Vec<i32>;
println!("ptr : {:?}",ptr);
// unsafe { (*ptr)[0] = 2; }
let ptr_ref_1 = Arc::new(AtomicPtr::new(ptr));
let a = thread::spawn(move || unsafe {
let ptr_inner = (ptr_ref_1).load(Ordering::SeqCst);
println!("ptr_inner_1 {:?}",ptr_inner);
(*ptr_inner).push(4);
println!("4 is done");
});
let ptr_ref_2 = Arc::new(AtomicPtr::new(ptr));
let b = thread::spawn(move || unsafe {
let ptr_inner = (ptr_ref_2).load(Ordering::SeqCst);
println!("ptr_inner_2 {:?}",ptr_inner);
(*ptr_inner).push(5);
println!("5 is done");
});
let ptr_ref_3 = Arc::new(AtomicPtr::new(ptr));
let c = thread::spawn(move || unsafe {
// Read value
// println!("{:?}",*(ptr_ref_3.load(Ordering::SeqCst)));
let ptr_inner = (ptr_ref_3).load(Ordering::SeqCst);
println!("ptr_inner_3 {:?}",ptr_inner);
(*ptr_inner).push(6);
println!("6 is done");
});
a.join().unwrap();
b.join().unwrap();
c.join().unwrap();
println!("final values {:?}",arr);
}
Run Code Online (Sandbox Code Playgroud)
95% 的运行正常,5% 的运行抛出以下错误
Output :
ptr : 0x16d65f008
ptr_inner_1 0x16d65f008
ptr_inner_2 0x16d65f008
5 is done
main(75339,0x16d867000) malloc: pointer 0x6000022a8010 being reallocated was not allocated
main(75339,0x16d867000) malloc: *** set a breakpoint in malloc_error_break to debug
Signal: SIGABRT (signal SIGABRT)
Run Code Online (Sandbox Code Playgroud)
尝试使用不安全的 Rust 和线程来改变对向量的单个指针的多个引用。我了解如何使用 Arc/Mutex 来更新多个线程中的值,但不确定这里的不安全生锈错误是什么。
这是一个简单的数据竞争,因为您试图Vec在没有任何同步的情况下改变三个不同线程中的一个。事实上,您正在使用的东西AtomicPtr在这里什么也没做。通常,当您使用 时AtomicPtr<T>,需要将其替换为另一个T指针或空指针,修改原始的T,然后将其放回去。
此代码始终是未定义的行为,但实际崩溃的 5% 可能是因为Vec在一个线程中重新分配,而另一个线程正在尝试写入它。
这段代码可能最好用通道来编写。