面试题答案
一键面试原理
在异步Rust编程中跨任务借用数据时,为避免悬空引用和保证并发安全,主要利用以下机制:
Arc
和Mutex
:Arc
(原子引用计数)用于在多个任务间共享数据,其内部维护引用计数,确保数据在所有引用被释放时才被销毁。Mutex
(互斥锁)用于保证同一时间只有一个任务能访问数据,防止数据竞争。Rc
和RefCell
:在单线程环境下,Rc
类似Arc
,但不支持跨线程。RefCell
提供运行时借用检查,允许内部可变性,结合Rc
可实现类似功能。async
函数的生命周期:async
函数返回的Future
带有自己的生命周期,确保在Future
执行期间,借用的数据有效。
代码示例
use std::sync::{Arc, Mutex};
use tokio::task;
#[tokio::main]
async fn main() {
let shared_data = Arc::new(Mutex::new(0));
let data_clone = shared_data.clone();
let handle = task::spawn(async move {
let mut data = data_clone.lock().unwrap();
*data += 1;
println!("Task incremented data to: {}", data);
});
let mut data = shared_data.lock().unwrap();
*data += 2;
println!("Main incremented data to: {}", data);
handle.await.unwrap();
let data = shared_data.lock().unwrap();
println!("Final data value: {}", data);
}
在这个示例中:
- 首先创建一个
Arc<Mutex<i32>>
类型的shared_data
,Arc
允许在多个任务间共享Mutex
包裹的i32
数据,Mutex
保证同一时间只有一个任务能访问和修改这个数据。 - 克隆一份
Arc
到新的变量data_clone
,并在新的异步任务中通过lock()
方法获取锁,修改数据并打印。 - 在主任务中同样获取锁,修改数据并打印。
- 等待异步任务完成,最后再次获取锁并打印最终的数据值。这样确保了跨任务借用数据时的并发安全,避免了悬空引用。