CondVar

作者: wangfp | 来源:发表于2023-12-27 11:01 被阅读0次
    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();
        }
    }
    

    相关文章

      网友评论

          本文标题:CondVar

          本文链接:https://www.haomeiwen.com/subject/exprndtx.html