面试题答案
一键面试在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();
}
}
在上述代码中:
Arc<Mutex<ProductInventory>>
用于在多个线程间安全共享ProductInventory
结构体。Arc
允许在多个线程间共享数据,Mutex
用于保护数据的可变性,确保同一时间只有一个线程可以访问并修改数据。- 在每个线程中,通过
lock()
方法获取锁。如果锁可用,lock()
方法返回一个MutexGuard
,它实现了Deref
和DerefMut
特性,允许像操作普通结构体引用一样操作ProductInventory
。 - 操作完成后,
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
),以此提高读多写少场景下的性能。