面试题答案
一键面试主要区别
- 读写特性:
std::sync::Mutex
只允许同一时间有一个线程访问其内部数据,无论是读操作还是写操作。这意味着每次访问都需要获取独占锁,读写操作相互阻塞。std::sync::RwLock
允许多个线程同时进行读操作,因为读操作不会修改数据,不会产生数据竞争。但是写操作需要独占锁,当有线程进行写操作时,其他读写线程都要等待。写操作会阻塞读操作,读操作也会阻塞写操作。
- 性能:
- 如果读操作远远多于写操作,
RwLock
性能更好,因为多个读操作可以并发执行。而Mutex
无论读写都只能一个线程访问,在多读场景下性能较差。 - 如果写操作频繁,
Mutex
和RwLock
性能差异不大,因为RwLock
的写操作也需要独占锁,并且可能因为等待读操作完成而有额外开销。
- 如果读操作远远多于写操作,
优先选择RwLock
的场景举例
假设有一个应用程序,它有一个共享的配置文件数据结构。大部分时间,多个线程只是读取这个配置文件中的数据,只有在配置更新时才进行写操作。例如:
use std::sync::{Arc, RwLock};
use std::thread;
fn main() {
let config = Arc::new(RwLock::new(Config { value: 42 }));
let mut handles = vec![];
for _ in 0..10 {
let config_clone = config.clone();
let handle = thread::spawn(move || {
let config = config_clone.read().unwrap();
println!("Read value: {}", config.value);
});
handles.push(handle);
}
let write_handle = thread::spawn(move || {
let mut config = config.write().unwrap();
config.value = 43;
println!("Write new value: {}", config.value);
});
for handle in handles {
handle.join().unwrap();
}
write_handle.join().unwrap();
}
struct Config {
value: i32,
}
在这个例子中,由于读操作频繁(10个读线程),写操作较少(1个写线程),使用RwLock
可以让读操作并发执行,提高整体性能。如果使用Mutex
,读操作也只能串行执行,会降低效率。