面试题答案
一键面试虚假唤醒
虚假唤醒是指线程在没有被明确通知(即没有调用条件变量的 notify
系列方法)的情况下,从等待条件变量的阻塞状态中苏醒。这在多线程编程中是可能发生的,因为底层的操作系统或线程库实现细节,例如信号中断等情况,可能导致线程意外地被唤醒。
处理方式及代码示例
在Rust中,处理虚假唤醒的常用方式是在条件变量的等待循环中不断检查相关条件,只有当条件真正满足时才退出等待。
以下是一个简单的代码示例:
use std::sync::{Arc, Condvar, Mutex};
use std::thread;
fn main() {
let pair = Arc::new((Mutex::new(false), Condvar::new()));
let pair2 = pair.clone();
thread::spawn(move || {
let (lock, cvar) = &*pair2;
let mut data = lock.lock().unwrap();
*data = true;
cvar.notify_one();
});
let (lock, cvar) = &*pair;
let mut data = lock.lock().unwrap();
while!*data {
data = cvar.wait(data).unwrap();
}
println!("Condition is true now.");
}
在上述代码中:
- 主线程和新线程共享一个由互斥锁
Mutex
和条件变量Condvar
组成的元组。 - 新线程在某个时刻修改共享数据
data
并调用cvar.notify_one()
通知等待的线程。 - 主线程在获取锁后,进入
while!*data
循环,每次循环等待条件变量,当被唤醒后重新检查data
是否为true
,只有data
为true
时才退出循环,从而有效处理了虚假唤醒的情况。