42·并发编程进阶

Mutex 互斥锁

Mutex 互斥锁

学习目标

  1. 理解 Mutex<T> 的作用
  2. 掌握 lock()try_lock()
  3. 理解 Arc<Mutex<T>> 共享状态

核心概念

基本用法

use std::sync::Mutex;

fn main() {
    let m = Mutex::new(5);

    {
        let mut num = m.lock().unwrap();
        *num = 6;
    }  // 锁在这里释放

    println!("{:?}", m);
}

多线程共享

use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    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 handle in handles {
        handle.join().unwrap();
    }

    println!("最终计数: {}", *counter.lock().unwrap());
}

try_lock

use std::sync::Mutex;

fn main() {
    let m = Mutex::new(42);

    match m.try_lock() {
        Ok(num) => println!("获取锁: {}", num),
        Err(_) => println!("锁被占用"),
    }
}

死锁避免

use std::sync::{Arc, Mutex};
use std::thread;

// ❌ 可能死锁:两个线程以不同顺序获取两把锁
// ✅ 始终以相同顺序获取锁

实践练习

练习 1:线程安全计数器

use std::sync::{Arc, Mutex};

struct Counter {
    value: Mutex<i32>,
}

impl Counter {
    fn new() -> Self {
        Counter { value: Mutex::new(0) }
    }

    fn increment(&self) {
        let mut val = self.value.lock().unwrap();
        *val += 1;
    }

    fn get(&self) -> i32 {
        *self.value.lock().unwrap()
    }
}

fn main() {
    let counter = Arc::new(Counter::new());
    let mut handles = vec![];

    for _ in 0..100 {
        let counter = Arc::clone(&counter);
        handles.push(thread::spawn(move || {
            counter.increment();
        }));
    }

    for h in handles { h.join().unwrap(); }
    println!("计数: {}", counter.get());
}

小结

操作语法
创建Mutex::new(value)
加锁mutex.lock()
释放自动(离开作用域)
多线程共享Arc<Mutex<T>>

练习编辑器

rust
Loading...