互斥锁(Mutex)
基本用法
rust
▶ Runuse std::sync::Mutex;
fn main() {
let m = Mutex::new(5);
// 获取锁
{
let mut num = m.lock().unwrap();
*num = 6;
} // 锁释放(Guard 离开作用域)
println!("m = {:?}", m.lock().unwrap()); // 6
}MutexGuard
rust
▶ Runuse std::sync::Mutex;
fn main() {
let data = Mutex::new(vec![1, 2, 3]);
// lock() 返回 MutexGuard
// MutexGuard 实现了 Deref 和 Drop
{
let mut guard = data.lock().unwrap();
guard.push(4);
// guard 离开作用域时自动释放锁
}
println!("{:?}", data.lock().unwrap());
}多线程共享
rust
▶ Runuse std::sync::{Arc, Mutex};
use std::thread;
fn main() {
// Arc + Mutex 实现线程安全共享
let counter = Arc::new(Mutex::new(0));
let mut handles = vec![];
for _ in 0..10 {
let counter = Arc::clone(&counter);
let handle = thread::spawn(move || {
let mut num = counter.lock().unwrap();
*num += 1;
});
handles.push(handle);
}
for h in handles {
h.join().unwrap();
}
println!("结果:{}", *counter.lock().unwrap()); // 10
}RwLock:读写锁
RwLock vs Mutex
┌─────────────────────────────────────────────────────┐
│ RwLock vs Mutex │
├─────────────────────────────────────────────────────┤
│ │
│ Mutex: │
│ • 独占锁,同一时间只有一个线程访问 │
│ • 适合写多读少 │
│ │
│ RwLock (Read-Write Lock): │
│ • 多个读锁可以同时存在 │
│ • 写锁独占 │
│ • 适合读多写少 │
│ │
└─────────────────────────────────────────────────────┘基本用法
rust
▶ Runuse std::sync::{Arc, RwLock};
use std::thread;
fn main() {
let data = Arc::new(RwLock::new(5));
// 多个读锁
let reader1 = data.read().unwrap();
let reader2 = data.read().unwrap();
println!("读取:{} {}", *reader1, *reader2);
drop(reader1);
drop(reader2);
// 写锁(独占)
let mut writer = data.write().unwrap();
*writer += 1;
println!("写入后:{}", *writer);
}读写优先级
rust
▶ Runuse std::sync::{Arc, RwLock};
use std::thread;
use std::time::Duration;
fn main() {
let data = Arc::new(RwLock::new(0));
// 读线程
for i in 0..5 {
let data = Arc::clone(&data);
thread::spawn(move || {
for _ in 0..3 {
let val = data.read().unwrap();
println!("读线程 {}:{}", i, *val);
thread::sleep(Duration::from_millis(10));
}
});
}
// 写线程
for i in 0..2 {
let data = Arc::clone(&data);
thread::spawn(move || {
for j in 1..=3 {
let mut val = data.write().unwrap();
*val = i * 10 + j;
println!("写线程:{}", *val);
thread::sleep(Duration::from_millis(50));
}
});
}
thread::sleep(Duration::from_millis(500));
}