/* * cv-rust.rs * * Alternating thread pattern using a mutex and condition variable in * Rust with an Arc as the object of synchronization. * * % rustc cv-rust.rs * % ./cv-rust * * Geoff Voelker * January 2019 */ use std::thread; use std::thread::JoinHandle; use std::sync::{Arc,Condvar,Mutex}; const ITERS: i32 = 10; fn alternate (lockcv: Arc<(Mutex, Condvar)>, whoami: &'static str) -> JoinHandle<()> { thread::spawn (move || { let &(ref lock, ref cv) = &*lockcv; let mut arc = lock.lock().unwrap(); for _ in 0..ITERS { println! ("{}", whoami); thread::yield_now(); // 'arbitrary' context switch cv.notify_one(); thread::yield_now(); // 'arbitrary' context switch arc = cv.wait(arc).unwrap(); thread::yield_now(); // 'arbitrary' context switch } // wake up whichever thread is still waiting on the cv cv.notify_one(); // the lock is implicitly released when leaving this scope }) } fn main () { let lockcv = Arc::new ((Mutex::new(false), Condvar::new())); let ping = alternate (lockcv.clone(), "ping"); let pong = alternate (lockcv.clone(), "pong"); ping.join().unwrap(); pong.join().unwrap(); }