MST

星途 面试题库

面试题:Rust 结构体可变性在多线程场景下的应用

在多线程环境中,使用 Rust 结构体。结构体有可变字段,需要在线程间共享并能被不同线程修改。请阐述如何通过 Rust 的同步原语(如 Mutex、Arc 等)来实现结构体可变性的安全控制,同时避免数据竞争和死锁。请给出一个简单的代码示例并解释其原理。
15.5万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
  1. 使用MutexArc实现
    • Mutex(互斥锁)用于保护共享数据,确保同一时间只有一个线程可以访问和修改数据,从而避免数据竞争。
    • Arc(原子引用计数)用于在多个线程间共享数据,因为Arc允许在多个所有者之间共享数据,并且它是线程安全的。
  2. 代码示例
use std::sync::{Arc, Mutex};
use std::thread;

// 定义一个包含可变字段的结构体
struct SharedData {
    value: i32,
}

fn main() {
    // 创建一个包含SharedData的Arc<Mutex<SharedData>>
    let shared_data = Arc::new(Mutex::new(SharedData { value: 0 }));

    let mut handles = vec![];

    for _ in 0..10 {
        // 克隆Arc,以便每个线程都有自己的引用
        let data = Arc::clone(&shared_data);
        let handle = thread::spawn(move || {
            // 锁定Mutex以获取对数据的可变引用
            let mut shared = data.lock().unwrap();
            shared.value += 1;
        });
        handles.push(handle);
    }

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

    // 打印最终结果
    let result = shared_data.lock().unwrap();
    println!("Final value: {}", result.value);
}
  1. 原理解释
    • 首先,我们定义了一个SharedData结构体,它包含一个可变字段value
    • 然后,使用Arc<Mutex<SharedData>>来创建共享数据。Arc允许在多个线程间共享Mutex<SharedData>,而Mutex确保对SharedData的访问是线程安全的。
    • 在每个线程中,通过data.lock().unwrap()来获取对SharedData的可变引用。lock方法会尝试获取锁,如果锁不可用,线程会阻塞直到锁可用。这里使用unwrap是为了简单处理可能的错误(在实际生产中应该更优雅地处理Result)。
    • 最后,主线程等待所有子线程完成后,再次获取锁并打印最终的value值。由于Mutex的保护,多个线程对value的修改不会导致数据竞争,并且由于合理使用锁,也不会出现死锁(在这个简单示例中,没有出现死锁的场景,比如没有循环依赖锁的情况)。