MST

星途 面试题库

面试题:Rust中如何通过引用可变性保证简单并发场景下的安全

假设有一个多线程程序,主线程创建一个可变的Vec<i32>,并希望在子线程中对其进行读取操作。请用Rust代码实现,并解释如何通过引用可变性来确保并发安全,同时说明在这个过程中借用规则是如何发挥作用的。
43.7万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

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

fn main() {
    let shared_vec = Arc::new(Mutex::new(vec![1, 2, 3]));
    let cloned_vec = shared_vec.clone();

    let handle = thread::spawn(move || {
        let mut vec_guard = cloned_vec.lock().unwrap();
        vec_guard.push(4);
        println!("子线程中: {:?}", vec_guard);
    });

    let mut vec_guard = shared_vec.lock().unwrap();
    println!("主线程中: {:?}", vec_guard);

    handle.join().unwrap();
}

解释如何确保并发安全以及借用规则的作用

  1. 确保并发安全
    • 使用Arc(原子引用计数)来在多个线程间共享数据,Arc允许我们在多个线程间克隆引用,它内部使用原子操作来管理引用计数,确保线程安全。
    • 使用Mutex(互斥锁)来保护Vec<i32>Mutex提供了互斥访问,通过lock方法获取锁(如果锁不可用则等待),这样同一时间只有一个线程可以访问Mutex内部的数据,从而确保了并发安全。
  2. 借用规则的作用
    • Rust的借用规则在编译时就确保内存安全和数据一致性。
    • 在上述代码中,Mutexlock方法返回一个MutexGuard,它实现了DerefDerefMut trait,当我们获取MutexGuard时,就相当于对Vec<i32>进行了可变借用。
    • 由于借用规则,同一时间只能有一个可变借用(在这种情况下,同一时间只有一个线程通过MutexGuardVec<i32>进行可变访问),这就避免了数据竞争(多个线程同时读写数据导致未定义行为)。当MutexGuard离开作用域时,它会自动释放锁,其他线程就可以获取锁并访问数据。