A condition variable is used to wait for something to happen to data protected by a mutex. It typically has three operations
wait: Take a locked mutex, atomically unlock the mutex and put the thread to sleep. When the thread awake by notification, immediately lock the mutex again.notify_one: wake up one waiting thread (if any)notify_all: wake up all waiting thread
A limitation of condition variable is that it must be paired with a mutex. In practice, it is fine since mutex is what we used to synchronize data anyway.
Below is an example in Rust 1
use std::sync::Condvar;
let queue = Mutex::new(VecDeque::new());
let not_empty = Condvar::new();
thread::scope(|s| {
s.spawn(|| {
// wait for item to arrive in queue
loop {
let mut q = queue.lock().unwrap();
let item = loop {
if let Some(item) = q.pop_front() {
break item;
} else {
q = not_empty.wait(q).unwrap();
}
};
drop(q);
dbg!(item);
}
});
for i in 0.. {
// put an item in queue and notify the other thread
queue.lock().unwrap().push_back(i);
not_empty.notify_one();
thread::sleep(Duration::from_secs(1));
}
});Implementations
- Rust
std::sync::Condvar
Footnotes
Footnotes
-
Chapter 1, Rust Atomics and Locks by Mara Bos (O’Reilly). Copyright 2023 Mara Bos, 978-1-098-11944-7. ↩