面试题答案
一键面试实际场景
- 资源等待:当线程需要等待某个资源可用时,如等待文件锁释放、数据库连接可用等。例如,在一个多线程文件读写程序中,若某个线程需要独占访问文件,但文件当前被其他线程锁定,此时该线程可以通过停放机制暂停,待文件锁释放后再被唤醒。
- 事件驱动:在事件驱动的系统中,线程可能需要等待特定事件发生。比如在图形用户界面(GUI)编程中,主线程等待用户输入事件(如点击按钮),当没有事件发生时,主线程可以停放,以节省系统资源,当事件触发时再被唤醒。
- 任务调度:在任务调度系统中,若有多个任务,当一个任务所需的前置条件未满足时,可以将执行该任务的线程停放,直到前置条件满足后唤醒线程继续执行。
使用 std::thread::park
和 std::thread::unpark
实现线程的停放与唤醒
use std::thread;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
fn main() {
let ready = Arc::new(AtomicBool::new(false));
let ready_clone = ready.clone();
let t = thread::spawn(move || {
// 模拟一些前期工作
thread::sleep(std::time::Duration::from_secs(2));
ready_clone.store(true, Ordering::SeqCst);
println!("线程准备就绪,唤醒主线程");
});
// 主线程等待直到 ready 为 true
while!ready.load(Ordering::SeqCst) {
thread::park();
}
println!("主线程被唤醒,继续执行");
t.join().unwrap();
}
在上述代码中:
- 定义了一个
AtomicBool
类型的ready
变量,用于表示某个条件是否准备好。 - 创建了一个新线程,在线程中模拟前期工作完成后,将
ready
设置为true
,并打印信息。 - 主线程通过
while
循环检查ready
的值,当ready
为false
时,调用thread::park()
停放自身,直到ready
变为true
,此时主线程被唤醒,继续执行后续代码。同时,主线程通过t.join()
等待新线程结束。