MST

星途 面试题库

面试题:Rust常函数线程安全之高级题

假设你正在编写一个使用Rust常函数的多线程程序,该常函数需要访问和修改共享资源。请阐述你将如何保证线程安全,同时利用Rust的所有权和借用机制,避免数据竞争和未定义行为。给出具体的代码示例并分析其实现原理。
36.2万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
  1. 使用Mutex来保证线程安全
    • 在Rust中,Mutex(互斥锁)是一种同步原语,用于保护共享资源,确保同一时间只有一个线程可以访问该资源。
    • 结合Rust的所有权和借用机制,可以有效避免数据竞争。
  2. 代码示例
use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    let shared_data = Arc::new(Mutex::new(0));
    let mut handles = vec![];

    for _ in 0..10 {
        let data = Arc::clone(&shared_data);
        let handle = thread::spawn(move || {
            let mut num = data.lock().unwrap();
            *num += 1;
        });
        handles.push(handle);
    }

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

    println!("Final value: {}", *shared_data.lock().unwrap());
}
  1. 实现原理分析
    • Arc(原子引用计数)
      • Arc用于在多个线程间共享数据。它提供了一种引用计数的方式来管理数据的生命周期。在这里,Arc<Mutex<i32>>Mutex<i32>包装起来,使得多个线程可以持有对这个Mutex的引用。
    • Mutex
      • Mutex保护内部数据(这里是i32类型的变量)。调用lock方法时,会尝试获取锁。如果锁可用,则返回一个MutexGuard智能指针,它实现了DerefMut trait,允许对内部数据进行可变借用。
      • MutexGuard离开作用域时(例如在let mut num = data.lock().unwrap();语句块结束时),它会自动释放锁,这确保了同一时间只有一个线程可以访问和修改共享数据,从而避免数据竞争。
    • 所有权和借用机制
      • Rust的所有权和借用机制在这个场景中起着关键作用。MutexGuard持有对Mutex内部数据的可变借用,这符合Rust的规则:同一时间只能有一个可变借用,从而避免了未定义行为。同时,Arc管理Mutex的所有权,确保Mutex在所有线程都使用完毕后才会被释放。