面试题答案
一键面试- 引入必要的库:
在Rust中,
std::sync
库提供了Mutex
和Condvar
。use std::sync::{Arc, Condvar, Mutex}; use std::thread;
- 定义共享数据结构:
定义一个共享队列来存放生产者生成的数据。
struct SharedQueue { queue: Vec<i32>, max_size: usize, }
- 初始化共享数据和同步原语:
使用
Arc
来共享数据,Mutex
来保护共享数据,Condvar
用于线程间的通知。let shared_queue = Arc::new(SharedQueue { queue: Vec::new(), max_size: 10, }); let mutex = Arc::new(Mutex::new(shared_queue)); let condvar = Arc::new(Condvar::new());
- 生产者线程:
生产者线程生成数字并放入共享队列。如果队列已满,生产者线程等待。
let producer = thread::spawn({ let mutex = mutex.clone(); let condvar = condvar.clone(); move || { for i in 0..100 { let mut data = mutex.lock().unwrap(); while data.queue.len() >= data.max_size { data = condvar.wait(data).unwrap(); } data.queue.push(i); condvar.notify_one(); } } });
- 消费者线程:
消费者线程从共享队列中取出数字并打印。如果队列为空,消费者线程等待。
let consumer = thread::spawn({ let mutex = mutex.clone(); let condvar = condvar.clone(); move || { loop { let mut data = mutex.lock().unwrap(); while data.queue.is_empty() { data = condvar.wait(data).unwrap(); } let num = data.queue.remove(0); println!("Consumed: {}", num); condvar.notify_one(); if num == 99 { break; } } } });
- 等待线程结束:
等待生产者和消费者线程完成任务。
producer.join().unwrap(); consumer.join().unwrap();
主要代码结构及关键步骤总结:
- 引入库:导入
std::sync
库中的Arc
、Condvar
和Mutex
。 - 定义共享数据结构:包含一个存放数据的
Vec
和队列最大容量。 - 初始化同步原语:使用
Arc
共享Mutex
保护的共享数据,并初始化Condvar
。 - 生产者线程:使用
Mutex
锁定共享数据,检查队列是否已满,满则通过Condvar
等待;放入数据后通过Condvar
通知其他线程。 - 消费者线程:使用
Mutex
锁定共享数据,检查队列是否为空,空则通过Condvar
等待;取出数据并打印后通过Condvar
通知其他线程。 - 等待线程结束:调用
join
方法等待生产者和消费者线程完成。