MST

星途 面试题库

面试题:Rust条件变量在多线程编程中的中等应用

请描述Rust中条件变量`Condvar`与互斥锁`Mutex`如何配合使用来实现线程间的同步。假设你有一个场景,主线程生产数据放入一个共享队列,工作线程从队列中消费数据,在这个场景下如何利用`Condvar`和`Mutex`来避免工作线程在队列为空时的无效循环等待?请给出相应的Rust代码示例并解释其原理。
43.8万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
  1. 原理
    • Mutex用于保护共享资源,这里的共享资源就是共享队列。它确保同一时间只有一个线程可以访问队列,防止数据竞争。
    • Condvar用于线程间的通知机制。当共享队列有数据时,主线程(生产者)通过Condvar通知等待在条件变量上的工作线程(消费者),工作线程被唤醒后获取Mutex锁访问队列中的数据,避免了在队列为空时的无效循环等待。
  2. 代码示例
use std::sync::{Arc, Condvar, Mutex};
use std::thread;

fn main() {
    let queue = Arc::new((Mutex::new(Vec::new()), Condvar::new()));
    let queue_clone = queue.clone();

    // 工作线程(消费者)
    let consumer = thread::spawn(move || {
        let (lock, cvar) = &*queue_clone;
        loop {
            let mut data = lock.lock().unwrap();
            while data.is_empty() {
                data = cvar.wait(data).unwrap();
            }
            let item = data.remove(0);
            println!("Consumed: {}", item);
        }
    });

    // 主线程(生产者)
    for i in 0..10 {
        let (lock, cvar) = &*queue;
        let mut data = lock.lock().unwrap();
        data.push(i);
        println!("Produced: {}", i);
        cvar.notify_one();
    }

    consumer.join().unwrap();
}
  1. 代码解释
    • 首先创建了一个Arc,内部包含一个Mutex和一个Condvar,用于共享队列的保护和线程间通知。
    • 工作线程(消费者)获取Mutex锁,检查队列是否为空。如果为空,通过Condvarwait方法等待通知,wait方法会释放Mutex锁并阻塞线程,当收到通知后重新获取Mutex锁。当队列有数据时,消费数据并打印。
    • 主线程(生产者)获取Mutex锁,向队列中添加数据,打印生产信息,然后通过Condvarnotify_one方法通知一个等待的工作线程。