MST

星途 面试题库

面试题:Rust数组在并发编程中如何保证数据安全

在Rust的并发编程场景下,使用数组作为共享数据时,可能会面临数据竞争的问题。请阐述如何利用Rust的所有权系统、借用规则以及相关并发原语(如Mutex)来确保数组数据在多线程环境中的安全访问和修改。并给出一个简单的示例代码说明。
29.6万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

1. 利用所有权系统、借用规则及并发原语确保安全访问

  • 所有权系统与借用规则:Rust的所有权系统确保每个值在任何时刻只有一个所有者,借用规则规定在同一时间要么只能有一个可变借用(用于修改数据),要么可以有多个不可变借用(用于读取数据),但不能同时存在可变和不可变借用。这在单线程环境中有效避免了数据竞争。
  • Mutex(互斥锁):在多线程环境下,Mutex(互斥锁)是一种常用的并发原语。它通过锁定机制来保护共享数据,同一时间只有一个线程能够获取锁并访问被保护的数据,从而避免数据竞争。当一个线程获取了Mutex的锁,其他线程必须等待锁被释放后才能获取锁并访问数据。

2. 示例代码

use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    // 使用Arc(原子引用计数)来在多个线程间共享数据,因为Arc可以跨线程使用
    let shared_array = Arc::new(Mutex::new([1, 2, 3, 4, 5]));

    let mut handles = vec![];
    for _ in 0..3 {
        let array_clone = shared_array.clone();
        let handle = thread::spawn(move || {
            // 获取锁,这一步可能会阻塞,直到锁可用
            let mut array = array_clone.lock().unwrap();
            for i in 0..array.len() {
                array[i] += 1;
            }
        });
        handles.push(handle);
    }

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

    // 主线程中再次获取锁并打印结果
    let result = shared_array.lock().unwrap();
    println!("{:?}", result);
}

在上述代码中:

  • Arc<Mutex<[i32; 5]>> 用于在多个线程间共享数组数据,Arc 提供跨线程的数据共享能力,Mutex 保护数组数据的安全访问。
  • 在每个线程中,通过 lock() 方法获取锁,成功获取锁后才能对数组进行修改。如果锁被其他线程持有,lock() 会阻塞当前线程,直到锁可用。
  • 最后主线程等待所有线程完成,并获取锁打印最终修改后的数组内容。这样就利用Rust的相关机制确保了数组数据在多线程环境中的安全访问和修改。