面试题答案
一键面试可能出现释放和获取顺序错误的场景
在多线程环境下,假设有两个线程thread1
和thread2
,共享一个资源resource
。thread1
先获取资源的锁,对资源进行一些写操作后,计划释放锁并通知thread2
可以读取。thread2
在接收到通知后尝试获取锁读取资源。如果在thread1
释放锁之前,thread2
就尝试获取锁,或者thread1
释放锁的操作没有正确同步到thread2
,就会出现释放和获取顺序错误,导致thread2
可能读取到未完全更新的资源数据。
使用Rust同步原语的代码实现思路
- 引入必要的库:
use std::sync::{Arc, Mutex};
use std::thread;
- 定义共享资源和同步原语:
let shared_resource = Arc::new(Mutex::new(0));
这里使用Arc
(原子引用计数指针)来在多个线程间共享数据,Mutex
(互斥锁)来保护共享资源的访问。
- 创建线程并进行操作:
let arc_clone = shared_resource.clone();
let handle1 = thread::spawn(move || {
let mut data = arc_clone.lock().unwrap();
*data += 1;
drop(data); // 手动释放锁,也可以让data离开作用域自动释放
});
let handle2 = thread::spawn(move || {
let data = shared_resource.lock().unwrap();
println!("Read value: {}", *data);
});
在上述代码中,thread1
(handle1
)获取锁,修改共享资源,然后释放锁。thread2
(handle2
)获取锁,读取共享资源。由于Mutex
的存在,保证了同一时间只有一个线程可以访问共享资源,避免了释放和获取顺序错误导致的数据不一致问题。
- 等待线程结束:
handle1.join().unwrap();
handle2.join().unwrap();
等待两个线程执行完毕,确保程序正常结束。