面试题答案
一键面试1. Rc
和 Arc
管理数据所有权简述
Rc
(引用计数):用于在单线程环境中管理数据的所有权。Rc
通过引用计数来跟踪指向数据的引用数量,当引用计数为0时,数据被自动释放。例如:
use std::rc::Rc;
fn main() {
let data = Rc::new(42);
let data_clone = data.clone();
assert_eq!(Rc::strong_count(&data), 2);
}
这里 data
和 data_clone
共享 Rc
内部的数据,每次 clone
操作会增加引用计数。
Arc
(原子引用计数):Arc
是Rc
的线程安全版本,适用于多线程环境。它使用原子操作来管理引用计数,确保在多个线程同时访问时,引用计数的增减操作是安全的。例如:
use std::sync::Arc;
fn main() {
let data = Arc::new(42);
let data_clone = data.clone();
assert_eq!(Arc::strong_count(&data), 2);
}
2. Arc
在多线程间传递数据的基本用法
use std::sync::Arc;
use std::thread;
fn main() {
let data = Arc::new(42);
let data_clone = data.clone();
let handle = thread::spawn(move || {
println!("Thread got data: {}", data_clone);
});
handle.join().unwrap();
println!("Main thread still has data: {}", data);
}
在这个例子中,Arc
包裹的数据 42
被克隆后传递到新线程中,两个线程可以安全地持有对同一数据的引用。
3. Arc
和 Mutex
结合使用的场景
当多个线程需要可变地访问共享数据时,Arc
本身无法提供对数据的可变访问,因为多个线程同时进行可变访问会导致数据竞争。这时需要结合 Mutex
(互斥锁)来实现安全的可变访问。例如:
use std::sync::{Arc, Mutex};
use std::thread;
fn main() {
let shared_data = Arc::new(Mutex::new(0));
let shared_data_clone = shared_data.clone();
let handle = thread::spawn(move || {
let mut data = shared_data_clone.lock().unwrap();
*data += 1;
});
handle.join().unwrap();
let data = shared_data.lock().unwrap();
println!("Final value: {}", *data);
}
在这个场景中,Arc
用于在多线程间共享 Mutex
包裹的数据,Mutex
确保同一时间只有一个线程能获取锁并对数据进行可变访问,从而避免数据竞争。