MST

星途 面试题库

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

请用Rust代码示例展示如何创建一个互斥锁,并在多线程环境下安全地访问被互斥锁保护的数据。说明在这个过程中,Rust如何通过所有权系统和类型系统来确保线程安全。
19.4万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

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

fn main() {
    // 创建一个被互斥锁保护的数据
    let data = Arc::new(Mutex::new(0));
    let mut handles = vec![];

    for _ in 0..10 {
        let data_clone = data.clone();
        // 每个线程尝试获取锁并修改数据
        let handle = thread::spawn(move || {
            let mut num = data_clone.lock().unwrap();
            *num += 1;
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }

    // 主线程获取锁并打印最终的数据
    let final_result = data.lock().unwrap();
    println!("Final result: {}", *final_result);
}

Rust通过所有权系统和类型系统确保线程安全的方式

  1. 所有权系统
    • 在Rust中,每个值都有一个唯一的所有者。当Mutex<T>创建时,T类型的数据的所有权被转移到Mutex内部。在上述代码中,Mutex拥有i32类型数据的所有权。
    • 当一个线程尝试通过lock()方法获取锁时,它会获取到一个MutexGuard类型的对象,这是一个智能指针。这个MutexGuard对象在作用域结束时会自动释放锁,从而确保锁的正确管理。例如在let mut num = data_clone.lock().unwrap();这行代码中,numMutexGuard<i32>类型,在其离开作用域时(例如线程函数结束),锁会被自动释放。
  2. 类型系统
    • Mutex<T>是一个泛型类型,它确保只有实现了SendSync trait的类型T才能被Mutex保护。Send trait表明类型的值可以安全地在线程间传递,Sync trait表明类型的值可以安全地被多个线程共享。i32类型实现了SendSync,所以可以被Mutex保护。
    • 类型系统还通过MutexGuard类型来确保只有获取到锁才能访问被保护的数据。由于MutexGuard实现了DerefDerefMut trait,所以可以像访问普通值一样访问被保护的数据,但只有在持有锁的情况下才能修改,这就保证了多线程环境下数据访问的安全性。