MST
星途 面试题库

面试题:Rust中条件变量使用示例的常见场景及实现

请描述在Rust中,条件变量通常会在哪些多线程同步场景下使用,并给出一个简单的条件变量使用示例代码,同时解释示例中每个关键部分的作用。
13.3万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

条件变量的使用场景

在Rust中,条件变量通常用于以下多线程同步场景:

  1. 生产者 - 消费者模型:生产者线程生产数据并将其放入共享队列,消费者线程从队列中取出数据进行处理。当队列为空时,消费者线程需要等待,直到有新的数据被生产出来,此时就可以使用条件变量。
  2. 资源获取等待:当一个线程需要获取某个资源,但该资源当前不可用时,线程可以等待,直到资源可用。例如,连接池中的连接数量有限,当所有连接都被占用时,新的请求需要等待直到有连接被释放。

示例代码

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 started = lock.lock().unwrap();
        *started = true;
        println!("Notifying the waiting thread...");
        cvar.notify_one();
    });

    let (lock, cvar) = &*pair;
    let mut started = lock.lock().unwrap();
    while!*started {
        started = cvar.wait(started).unwrap();
    }
    println!("The waiting thread has been notified!");
}

关键部分解释

  1. 创建条件变量和互斥锁
let pair = Arc::new((Mutex::new(false), Condvar::new()));

这里通过Arc(原子引用计数)来创建一个包含互斥锁Mutex和条件变量Condvar的元组。Mutex用于保护共享数据,Condvar用于线程间的通知和等待。

  1. 线程1(通知线程)
thread::spawn(move || {
    let (lock, cvar) = &*pair2;
    let mut started = lock.lock().unwrap();
    *started = true;
    println!("Notifying the waiting thread...");
    cvar.notify_one();
});

这个线程获取锁并修改共享状态startedtrue,然后调用cvar.notify_one()通知等待在条件变量上的一个线程。

  1. 线程2(等待线程)
let (lock, cvar) = &*pair;
let mut started = lock.lock().unwrap();
while!*started {
    started = cvar.wait(started).unwrap();
}
println!("The waiting thread has been notified!");

这个线程获取锁并检查共享状态started。如果startedfalse,则调用cvar.wait(started)进入等待状态。wait方法会释放锁并阻塞线程,直到收到通知。当收到通知后,wait方法重新获取锁并返回被修改后的锁的所有权,线程继续检查started状态,直到startedtrue