MST

星途 面试题库

面试题:Rust读写锁在多线程环境下的基础使用场景

请描述在Rust中,读写锁(如`std::sync::RwLock`)适合在哪些多线程场景下使用?并举例说明如何使用`RwLock`来保护共享数据,使得多个线程可以安全地读取数据,同时保证写操作的原子性。
15.5万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

适用场景

  1. 读多写少场景:当大部分操作是读取共享数据,而写操作相对较少时,RwLock能显著提升性能。因为多个线程可以同时获取读锁进行读取,不会相互阻塞,只有在写操作时才需要独占锁。例如,一个存储配置信息的共享数据结构,程序启动后配置信息很少改变,但在运行过程中有大量线程需要读取这些配置。
  2. 数据一致性要求高:确保在写操作时,其他线程不能读取或写入,保证数据的原子性修改,避免数据处于不一致状态。比如在银行账户余额的操作场景,在更新余额时必须保证操作的原子性,防止其他线程在更新过程中读取到错误的余额。

使用示例

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

fn main() {
    // 创建一个RwLock包裹的共享数据
    let data = Arc::new(RwLock::new(0));

    // 定义10个读取线程
    let mut read_handles = vec![];
    for _ in 0..10 {
        let data_clone = Arc::clone(&data);
        let handle = thread::spawn(move || {
            let value = data_clone.read().unwrap();
            println!("Read value: {}", value);
        });
        read_handles.push(handle);
    }

    // 定义一个写入线程
    let write_handle = thread::spawn(move || {
        let mut value = data.write().unwrap();
        *value = 42;
        println!("Write value: {}", value);
    });

    // 等待所有读取线程完成
    for handle in read_handles {
        handle.join().unwrap();
    }
    // 等待写入线程完成
    write_handle.join().unwrap();
}

在上述代码中:

  1. Arc用于在多个线程间共享RwLock
  2. 多个读取线程通过data.read().unwrap()获取读锁读取数据。
  3. 写入线程通过data.write().unwrap()获取写锁修改数据,保证写操作的原子性。