CondVar
2023-12-27 本文已影响0人
wangfp
use std::sync::{Arc, Condvar, Mutex};
use std::{thread};
use std::time::Duration;
fn main() {
let pair = Arc::new((Mutex::new(false), Condvar::new()));
let pair2 = pair.clone();
thread::spawn(move || {
thread::sleep(Duration::from_millis(100));
let (lock, cvar) = &*pair2;
thread::sleep(Duration::from_millis(500));
cvar.notify_one();
println!("notify first");
let mut started = lock.lock().unwrap();
thread::sleep(Duration::from_millis(500));
*started = true;
cvar.notify_one();
println!("notify second");
});
// thread::sleep(Duration::from_millis(800));
let (lock, cvar) = &*pair;
let mut started = lock.lock().unwrap();
// mutex 锁的是资源,可以用CondVar进行资源状态变化的判断
// 因此,CondVar的用法是先判断资源状态是否符合当前要求,如果不符合,则调用wait(释放锁),并等待被通知
// 使用while的原因在于资源的状态可能未变更为预期的状态,还需要再等待;或者可能有多个ConVar在等待,但只触发了一次通知
println!("before: {:?}", started);
while !*started {
started = cvar.wait(started).unwrap(); // 这里会释放锁,并监控锁被再次释放的时机
}
println!("after: {:?}", started);
// {
// let first = S{a: 10};
// let mut second: [MaybeUninit<S>; 10] = unsafe {
// MaybeUninit::uninit().assume_init()
// };
//
// for (i, elem) in second[..5].iter_mut().enumerate() {
// elem.write(S{ a: i });
// }
// for elem in second[..5].iter_mut() {
// unsafe {
// ptr::drop_in_place(elem as *mut _ as *mut S);
// }
// }
// // let mut second = ManuallyDrop::new(S{a: 20});
//
// // unsafe {
// // ptr::drop_in_place(second.as_mut_ptr());
// // }
// }
println!("done");
}
#[derive(Debug)]
struct S {
a: usize,
}
impl Drop for S {
fn drop(&mut self) {
println!("drop {:?}", self);
}
}
struct Semaphore {
condvar: Condvar,
counter: Mutex<i32>,
}
impl Semaphore {
pub fn new(max: i32) -> Self {
Semaphore {
condvar: Condvar::new(),
counter: Mutex::new(max),
}
}
pub fn acquire(&mut self) {
let mut count = self.counter.lock().unwrap();
while *count <= 0 {
count = self.condvar.wait(count).unwrap(); // 这里会释放锁,保证其它线程获取到锁;直到被notify
}
*count -= 1;
}
pub fn release(&mut self) {
let mut count = self.counter.lock().unwrap();
*count += 1;
self.condvar.notify_one();
}
}