MST

星途 面试题库

面试题:Rust中可变借用在并发控制场景下的规则应用

在Rust中,假设有一个多线程程序,主线程创建了一个可变的Vec<i32>,然后启动两个子线程,其中一个子线程需要对这个Vec进行修改,另一个子线程需要读取这个Vec。请描述如何使用可变借用和不可变借用规则来保证程序的正确性,并给出相应的代码示例。
29.9万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
  1. 使用Mutex进行同步
    • 在Rust中,为了在多线程环境下安全地访问和修改共享数据,我们可以使用Mutex(互斥锁)。Mutex允许我们通过获取锁来控制对共享数据的访问,从而保证同一时间只有一个线程可以访问数据。
    • 可变借用意味着在借用期间,其他任何线程都不能读取或修改该数据。不可变借用意味着在借用期间,其他线程可以读取但不能修改该数据。
  2. 代码示例
use std::sync::{Arc, Mutex};
use std::thread;

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

    let mut handles = vec![];

    // 第一个子线程修改Vec
    let shared_vec_clone1 = shared_vec.clone();
    let handle1 = thread::spawn(move || {
        let mut data = shared_vec_clone1.lock().unwrap();
        data.push(4);
    });
    handles.push(handle1);

    // 第二个子线程读取Vec
    let shared_vec_clone2 = shared_vec.clone();
    let handle2 = thread::spawn(move || {
        let data = shared_vec_clone2.lock().unwrap();
        println!("Data in second thread: {:?}", data);
    });
    handles.push(handle2);

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

在上述代码中:

  • Arc(原子引用计数)用于在多个线程间共享Mutex包裹的VecArc允许我们在多个线程间克隆引用,并且在引用计数为0时自动释放内存。
  • Mutex用于保护Vec。通过lock方法获取锁,如果获取成功(返回Result中的Ok),则可以进行可变或不可变借用。
  • 第一个子线程获取可变借用(通过mut data = shared_vec_clone1.lock().unwrap();)来修改Vec
  • 第二个子线程获取不可变借用(通过let data = shared_vec_clone2.lock().unwrap();)来读取Vec

这样,通过Mutex的机制,我们遵循了Rust的可变借用和不可变借用规则,确保了多线程程序的正确性。