MST

星途 面试题库

面试题:Rust中如何确保Vec<T>在线程间安全使用

在Rust中,通常情况下`Vec<T>`不是线程安全的。请阐述如何通过一些机制,比如`Arc`和`Mutex`,使得`Vec<T>`能够在线程间安全地共享和操作,给出相应的代码示例并解释每一步的作用。
25.8万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
  1. 引入必要的包: 在Rust中,Arc(原子引用计数)和Mutex(互斥锁)来自标准库,所以无需额外引入外部包。
use std::sync::{Arc, Mutex};
use std::thread;
  1. 创建线程安全的Vec<T>: 使用ArcMutex来包装Vec<T>Arc用于在多个线程间共享数据,Mutex用于保证同一时间只有一个线程能访问数据。
let shared_vec = Arc::new(Mutex::new(vec![1, 2, 3]));

这里创建了一个Arc包裹着Mutex,而Mutex又包裹着一个Vec<i32>

  1. 在多线程中使用
let mut handles = vec![];
for _ in 0..3 {
    let clone = shared_vec.clone();
    let handle = thread::spawn(move || {
        let mut vec = clone.lock().unwrap();
        vec.push(4);
        println!("{:?}", vec);
    });
    handles.push(handle);
}

for handle in handles {
    handle.join().unwrap();
}
  • let clone = shared_vec.clone();:由于Arc是引用计数的,clone方法会增加引用计数,使得每个线程都能持有一个指向共享数据的Arc
  • let mut vec = clone.lock().unwrap();:这里调用lock方法尝试获取Mutex的锁。如果获取成功(返回Result类型,unwrap方法在成功时返回内部值,失败时会panic),就可以对Vec进行操作。
  • vec.push(4);:向Vec中添加一个元素。
  • println!("{:?}", vec);:打印当前Vec的内容。
  • 最后通过join方法等待所有线程执行完毕。

完整代码如下:

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![];
    for _ in 0..3 {
        let clone = shared_vec.clone();
        let handle = thread::spawn(move || {
            let mut vec = clone.lock().unwrap();
            vec.push(4);
            println!("{:?}", vec);
        });
        handles.push(handle);
    }

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