MST
星途 面试题库

面试题:Rust线程中如何进行安全的数据共享

在Rust中,线程间共享数据需要考虑安全性,防止数据竞争。请阐述如何使用`Arc`和`Mutex`或`RwLock`来安全地在线程间共享数据,并给出一个简单的代码示例。
13.9万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
  1. ArcMutexRwLock的作用

    • Arc(Atomically Reference - Counted):用于在堆上分配数据,并通过引用计数来管理其生命周期,允许多个线程持有指向同一数据的共享引用。它的设计目的是线程安全的引用计数。
    • Mutex(Mutual Exclusion):互斥锁,通过锁定机制来保证同一时间只有一个线程可以访问其保护的数据,防止数据竞争。
    • RwLock(Read - Write Lock):读写锁,允许多个线程同时进行读操作,但只允许一个线程进行写操作。写操作会阻止其他读和写操作,而读操作之间不会相互阻止。
  2. 使用ArcMutex共享数据示例

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. 使用ArcRwLock共享数据示例
use std::sync::{Arc, RwLock};
use std::thread;

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

    for _ in 0..5 {
        let data = Arc::clone(&shared_data);
        let handle = thread::spawn(move || {
            let num = data.read().unwrap();
            println!("Read value: {}", num);
        });
        handles.push(handle);
    }

    let data = Arc::clone(&shared_data);
    let write_handle = thread::spawn(move || {
        let mut num = data.write().unwrap();
        *num += 1;
    });
    handles.push(write_handle);

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

    println!("Final value: {}", *shared_data.read().unwrap());
}

在上述代码中:

  • 第一个示例使用ArcMutex,多个线程尝试对共享数据进行修改,Mutex确保每次只有一个线程可以修改数据。
  • 第二个示例使用ArcRwLock,多个读线程可以同时读取共享数据,而写线程在进行写操作时会独占数据,防止其他线程(读或写)访问。