MST
星途 面试题库

面试题:Rust商店示例中如何实现基本的线程安全数据共享

在Rust商店示例场景下,假设有一个商品库存的结构体,需要在多个线程间安全共享并修改库存数量,简述使用什么Rust机制(如锁、原子类型等)来实现,并给出简单代码示例。
13.8万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

在Rust中,要在多个线程间安全共享并修改商品库存结构体中的库存数量,可以使用Mutex(互斥锁)或RwLock(读写锁,适用于读多写少场景)结合Arc(原子引用计数指针)来实现。以下以Mutex为例:

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

// 定义商品库存结构体
struct ProductInventory {
    stock: i32,
}

fn main() {
    // 使用Arc和Mutex来共享和保护库存结构体
    let shared_inventory = Arc::new(Mutex::new(ProductInventory { stock: 100 }));

    let mut handles = vec![];
    for _ in 0..10 {
        let inventory = Arc::clone(&shared_inventory);
        let handle = thread::spawn(move || {
            let mut inventory = inventory.lock().unwrap();
            inventory.stock -= 1;
            println!("当前库存: {}", inventory.stock);
        });
        handles.push(handle);
    }

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

在上述代码中:

  1. Arc<Mutex<ProductInventory>> 用于在多个线程间安全共享 ProductInventory 结构体。Arc 允许在多个线程间共享数据,Mutex 用于保护数据的可变性,确保同一时间只有一个线程可以访问并修改数据。
  2. 在每个线程中,通过 lock() 方法获取锁。如果锁可用,lock() 方法返回一个 MutexGuard,它实现了 DerefDerefMut 特性,允许像操作普通结构体引用一样操作 ProductInventory
  3. 操作完成后,MutexGuard 离开作用域时会自动释放锁。

如果是读多写少的场景,可以考虑使用RwLock,代码示例如下:

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

struct ProductInventory {
    stock: i32,
}

fn main() {
    let shared_inventory = Arc::new(RwLock::new(ProductInventory { stock: 100 }));

    let mut handles = vec![];
    for _ in 0..5 {
        let inventory = Arc::clone(&shared_inventory);
        // 读操作线程
        let read_handle = thread::spawn(move || {
            let inventory = inventory.read().unwrap();
            println!("读操作,当前库存: {}", inventory.stock);
        });
        handles.push(read_handle);
    }

    for _ in 0..2 {
        let inventory = Arc::clone(&shared_inventory);
        // 写操作线程
        let write_handle = thread::spawn(move || {
            let mut inventory = inventory.write().unwrap();
            inventory.stock -= 1;
            println!("写操作,当前库存: {}", inventory.stock);
        });
        handles.push(write_handle);
    }

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

在这个使用RwLock的示例中,读操作可以并发执行(通过read()方法获取ReadGuard),而写操作则需要独占锁(通过write()方法获取WriteGuard),以此提高读多写少场景下的性能。