gpt4 book ai didi

concurrency - 如何使用 Condvar 和 Mutex 监控变化

转载 作者:行者123 更新时间:2023-11-29 08:25:23 24 4
gpt4 key购买 nike

我有一个共享 Vec<CacheChange> .每当一个新的CacheChange写的我想唤醒读者。我记得一个Condvar有利于在谓词/情况准备就绪时发出信号,即当 Vec 时已修改。

所以我花了一些时间创建了一个 Monitor拥有 Vec 的抽象并提供waitlock语义。

现在的问题是我不知道什么时候重置Condvar .给读者合理的时间来命中谓词并努力持有锁的好方法是什么?在关闭 condvar 之前?我接近Condvar走错路了吗?

这是 Rust 代码,但这更多的是关于多个读者之间精确并发访问/通知的基础问题。

pub struct Monitor<T>(
sync::Arc<MonitorInner<T>>
);

struct MonitorInner<T> {
data: sync::Mutex<T>,
predicate: (sync::Mutex<bool>, sync::Condvar)
}

impl<T> Monitor<T> {
pub fn wait(&self) -> Result<(),sync::PoisonError<sync::MutexGuard<bool>>> {
let mut open = try!(self.0.predicate.0.lock());
while !*open {
open = try!(self.0.predicate.1.wait(open));
}
Ok(())
}

pub fn lock(&self) -> Result<sync::MutexGuard<T>, sync::PoisonError<sync::MutexGuard<T>>> {
self.0.data.lock()
}

pub fn reset(&mut self) -> Result<(),sync::PoisonError<sync::MutexGuard<bool>>> {
let mut open = try!(self.0.predicate.0.lock());
*open = false;
Ok(())
}

pub fn wakeup_all(&mut self) -> Result<(),sync::PoisonError<sync::MutexGuard<bool>>> {
let mut open = try!(self.0.predicate.0.lock());
*open = true;
self.0.predicate.1.notify_all();
Ok(())
}
}

在第一次叫醒电话后,我的读者可能会错过阅读。可能是因为当谓词再次切换时它们仍然持有数据锁。我在我的测试代码中看到了这一点,只有一个读者和一个作者。

然后是何时重置 Monitor 的复杂问题, 理想情况下,在所有读者都有机会查看数据后,它会被锁定。如果读者忽略他们的监视器(不保证他们应该为每个唤醒调用服务),这可能会导致死锁问题。

我是否需要使用某种具有超时功能的读者跟踪系统,并在新数据到达时跟踪监视器读取仍在服务中?是否有我应该注意的现有范例?

最佳答案

最简单的解决方案是使用计数器而不是 bool 值。

struct MonitorInner<T> {
data: sync::Mutex<T>,
signal: sync::Condvar,
counter: sync::AtomicUsize,
}

然后,每次更新完成时,计数器都会递增。它从不重置,因此不存在何时重置的问题。

当然,这意味着读者应该记住上次被唤醒时计数器的值。

关于concurrency - 如何使用 Condvar 和 Mutex 监控变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40254677/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com