文章阅读
Rust中的Arc和Mutex互斥锁在线程中的使用
2025/12/1668 次阅读3 分钟
use std::thread;
use std::sync::Arc;
use std::sync::Mutex;
/**
Arc 代表原子引用计数,它是使用原子操作的RC的线程安全版本
Arc::clone 在执行原子操作方面有开销,但是在此之后,T可以随意使用,而且没有任何开销
注意在循环里面使用,Arc不会使用垃圾回收器检测引用循环
**/
fn main1() {
let v = Arc::new(vec![10,20,30]);
let mut handles = Vec::new();
for _ in 1..5 {
let v= Arc::clone(&v);
handles.push(thread::spawn(move || {
let thread_id = thread::current().id();
println!("{thread_id:?}:{v:?}");
}));
}
handles.into_iter().for_each(|h| h.join().unwrap());
println!("v:{v:?}")
}
/**
互斥器
rust中的互斥器看起来就像是包含一个元素的集合,其中的元素就是受保护的数据
在访问受保护的数据之前,不可能忘记获取互斥量
你可以通过获取锁,从&Mutex<T>中获取&mut T ,MutexGuard 能够确保&mut T存在的时间不会比持有锁的时间更长
读写锁版本==>> RwLock
为什么lock会返回Result?
如果持有Mutex的线程发生panic ,Mutex便会中毒并发出信号,表明其所保护的数据可能处于不一致的状态
对中毒的互斥量调用lock()就会失败,并将显示PoisonError(poison:翻译过来就是毒药的意思)
无论如何,你可以对这个错误调用into_inner()来恢复数据
**/
fn main2(){
let v = Mutex::new(vec![10,20,30]);
println!("v:{:?}",v.lock().unwrap());
{
let mut guard = v.lock().unwrap();
guard.push(40);
}
println!("v:{:?}",v.lock().unwrap());
}
// fn main3(){
// let mut v = vec![10, 20, 30];
// let handle = thread::spawn(||{
// v.push(10);
// });
// v.push(1000);
// handle.join().unwrap();
// println!("v:{v:?}");
// }
///解决上面main3的问题
///
///
/// 注意:把Mutex封装在Arc里面是一种在线程之间共享可变状态的常见模式
/// v:Arc<_>必须先克隆为v2,让后才能移动到另一个线程中,注意:lambda签名中添加了move
fn main(){
let v = Arc::new(Mutex::new(vec![10,20,30]));
let v2 = Arc::clone(&v);
let handle = thread::spawn(move||{
let mut v2 = v2.lock().unwrap();
v2.push(10);
});
{
let mut v = v.lock().unwrap();
v.push(1000);
}
handle.join().unwrap();
println!("v:{v:?}");
}