MST

星途 面试题库

面试题:Rust互斥锁在并发场景下的基本使用

请用Rust代码示例展示如何在多线程环境中使用互斥锁来保护共享数据,要求至少创建两个线程,一个线程对共享数据进行修改,另一个线程读取共享数据,并说明`Mutex`结构体的主要方法及其作用。
47.7万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    // 使用Arc来实现跨线程的数据共享
    let shared_data = Arc::new(Mutex::new(0));

    // 创建第一个线程,用于修改共享数据
    let thread1 = thread::spawn({
        let shared_data = Arc::clone(&shared_data);
        move || {
            let mut data = shared_data.lock().unwrap();
            *data += 1;
        }
    });

    // 创建第二个线程,用于读取共享数据
    let thread2 = thread::spawn({
        let shared_data = Arc::clone(&shared_data);
        move || {
            let data = shared_data.lock().unwrap();
            println!("Read data: {}", *data);
        }
    });

    // 等待线程结束
    thread1.join().unwrap();
    thread2.join().unwrap();
}

Mutex结构体的主要方法及其作用:

  1. lock
    • 作用:尝试获取锁。如果锁可用,则返回一个MutexGuard智能指针,它实现了DerefDrop trait,当MutexGuard离开作用域时,会自动释放锁。如果锁当前被其他线程持有,调用线程会被阻塞,直到锁可用。
    • 示例let mut data = shared_data.lock().unwrap();
  2. try_lock
    • 作用:尝试获取锁,但不会阻塞。如果锁可用,返回一个Result<MutexGuard, PoisonError<MutexGuard>>,其中Ok包含MutexGuardErr表示获取锁失败(例如锁被毒死,即持有锁的线程发生了恐慌)。
    • 示例let result = shared_data.try_lock();
  3. into_inner
    • 作用:如果锁当前未被任何线程持有,将Mutex内部封装的数据取出,同时销毁Mutex
    • 示例let data = shared_data.into_inner().unwrap();
  4. poison
    • 作用:将Mutex标记为“毒死”状态。当持有锁的线程发生恐慌时,Mutex会自动进入毒死状态,后续对锁的操作(除了try_lock)都会返回PoisonError
    • 示例shared_data.poison(); (通常不需要手动调用,恐慌时会自动处理)