MST
星途 面试题库

面试题:Rust中互斥锁的基本使用场景

请描述在Rust编程中,互斥锁(Mutex)通常会在哪些场景下被使用?并给出一个简单的代码示例来展示互斥锁如何保护共享数据。
50.4万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

互斥锁(Mutex)的使用场景

  1. 多线程访问共享资源:当多个线程需要访问和修改同一份数据时,为了避免数据竞争(data race)导致未定义行为,使用互斥锁来确保同一时间只有一个线程能访问该共享资源。例如,多个线程可能都需要对一个全局计数器进行增减操作,此时就需要用互斥锁来保护计数器。
  2. 共享可变状态:在程序中存在共享的可变数据结构,且需要在不同线程间安全地访问和修改时,互斥锁是常用的手段。比如一个共享的哈希表,不同线程可能会向其中插入或读取数据,就需要通过互斥锁来保证数据的一致性。

代码示例

use std::sync::{Mutex, Arc};
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!("Result: {}", *counter.lock().unwrap());
}

在上述代码中:

  1. 首先创建了一个被 Mutex 包裹的 counter,类型为 Arc<Mutex<i32>>Arc 用于在多个线程间共享所有权,Mutex 用于保护内部的 i32 数据。
  2. 通过循环创建10个线程,每个线程尝试获取 Mutex 的锁,成功获取锁后对 counter 进行加1操作。
  3. 主线程等待所有子线程完成后,获取锁并打印最终的 counter 值。这样通过 Mutex 确保了 counter 在多线程环境下的安全访问和修改。