MST
星途 面试题库

面试题:Rust线程同步函数复杂场景应用

假设你正在开发一个多线程应用,其中有多个读线程和少量写线程,读操作频繁且写操作会改变共享数据。请描述如何使用Rust的线程同步函数来高效地管理共享资源,包括对`Arc`、`RwLock`等的使用,并给出相应代码示例及解释。
40.5万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
  1. ArcRwLock 的作用

    • Arc(原子引用计数)用于在多个线程间共享数据,它允许数据在堆上分配,并在多个线程间安全地引用。
    • RwLock(读写锁)用于保护共享数据,允许多个读操作并发执行,但写操作必须独占访问,以避免数据竞争。
  2. 代码示例

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

fn main() {
    // 创建一个Arc<RwLock<T>>来保护共享数据
    let data = Arc::new(RwLock::new(0));

    // 存储线程句柄的向量
    let mut handles = vec![];

    // 创建多个读线程
    for _ in 0..10 {
        let data_clone = data.clone();
        let handle = thread::spawn(move || {
            let value = data_clone.read().unwrap();
            println!("Read value: {}", value);
        });
        handles.push(handle);
    }

    // 创建写线程
    let data_clone = data.clone();
    let write_handle = thread::spawn(move || {
        let mut value = data_clone.write().unwrap();
        *value += 1;
        println!("Write value: {}", value);
    });
    handles.push(write_handle);

    // 等待所有线程完成
    for handle in handles {
        handle.join().unwrap();
    }
}
  1. 代码解释
    • let data = Arc::new(RwLock::new(0));:创建一个 Arc<RwLock<i32>> 实例,初始值为0。Arc 允许在多个线程间共享 RwLockRwLock 用于保护内部的 i32 数据。
    • 读线程部分
      • let data_clone = data.clone();:为每个读线程克隆 Arc,这样每个线程都有自己对共享数据的引用。
      • let value = data_clone.read().unwrap();:调用 read 方法获取读锁,这允许其他读操作并发执行。unwrap 用于在获取锁失败时(在这个简单示例中不会发生)使程序崩溃并打印错误信息。
    • 写线程部分
      • let data_clone = data.clone();:同样克隆 Arc 给写线程。
      • let mut value = data_clone.write().unwrap();:调用 write 方法获取写锁,这会独占访问共享数据,直到写操作完成。
      • *value += 1;:修改共享数据。
    • for handle in handles { handle.join().unwrap(); }:等待所有线程完成,确保所有读和写操作都执行完毕。