MST

星途 面试题库

面试题:Rust条件变量中如何处理虚假唤醒问题

在Rust中使用条件变量时,虚假唤醒是一个需要考虑的问题。请阐述虚假唤醒是什么,以及在Rust的条件变量使用场景下,如何通过代码逻辑来有效处理虚假唤醒,给出具体的代码示例说明。
32.2万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

虚假唤醒

虚假唤醒是指线程在没有被明确通知(即没有调用条件变量的 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.");
}

在上述代码中:

  1. 主线程和新线程共享一个由互斥锁 Mutex 和条件变量 Condvar 组成的元组。
  2. 新线程在某个时刻修改共享数据 data 并调用 cvar.notify_one() 通知等待的线程。
  3. 主线程在获取锁后,进入 while!*data 循环,每次循环等待条件变量,当被唤醒后重新检查 data 是否为 true,只有 datatrue 时才退出循环,从而有效处理了虚假唤醒的情况。