use std::sync::{Arc, Condvar, Mutex};
use std::thread;
use std::collections::VecDeque;
fn main() {
let queue = Arc::new((Mutex::new(VecDeque::new()), Condvar::new()));
let queue_clone = queue.clone();
// 生产者线程
let producer = thread::spawn(move || {
for i in 0..10 {
let (lock, cvar) = &*queue_clone;
let mut queue = lock.lock().unwrap();
queue.push_back(i);
println!("Produced: {}", i);
queue = cvar.notify_one().wait(queue).unwrap();
}
});
// 消费者线程
let consumer = thread::spawn(move || {
let (lock, cvar) = &*queue;
loop {
let mut queue = lock.lock().unwrap();
while queue.is_empty() {
queue = cvar.wait(queue).unwrap();
}
let item = queue.pop_front().unwrap();
println!("Consumed: {}", item);
if item == 9 {
break;
}
}
});
producer.join().unwrap();
consumer.join().unwrap();
}
条件变量在这里起到的作用:
- 线程同步:条件变量
Condvar
用于协调生产者和消费者线程之间的同步。当共享队列空时,消费者线程可以通过 cvar.wait(queue)
进入等待状态,释放它对互斥锁 Mutex
的持有,使得其他线程(如生产者线程)可以获取锁并向队列中添加数据。
- 唤醒等待线程:生产者线程在向共享队列中添加数据后,通过
cvar.notify_one()
唤醒一个等待在条件变量上的线程(这里就是消费者线程),通知消费者队列中有新的数据可以处理。这样消费者线程就会重新获取互斥锁并从队列中取出数据进行处理。