나는 Vec<CacheChange>
을 공유했습니다. 새로운 CacheChange
이 쓰여질 때마다 나는 독자들을 깨우고 싶다. 프리디 케이트/상황이 준비되었을 때, 즉 Vec
이 수정되었을 때 Condvar
이 시그널링에 좋다는 것을 기억합니다.Condvar 및 Mutex로 변경 사항을 모니터링하는 방법
그래서 Vec
을 소유하고 wait
및 lock
의미 체계를 제공하기 위해 Monitor
추상화를 만드는 데 시간을 보냈습니다.
지금 문제는 Condvar
을 언제 재설정해야할지 모르겠다. 독자가 술어를 치고 자물쇠를 들고가는 길에 합당한 시간을주는 좋은 방법은 무엇입니까? 아내를 닫기 전에? 내가 잘못된 방법으로 Condvar
에 접근하고 있습니까?
이것은 녹 부호이지만 여러 독자 간의 정확한 동시 액세스/알림을위한 기본 사항에 대한 질문입니다.
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
을 재설정해야하는 번거 로움이 있습니다. 모든 독자가 데이터를 볼 기회가있는 것이 이상적입니다. 독자가 모니터를 무시하면 교착 상태 문제가 발생할 수 있습니다 (모든 깨우기 호출을 처리해야한다는 보장이 없음).
모니터링 판독기가 계속 서비스되는 동안 새 데이터가 도착하면 시간 초과와 함께 일종의 판독기 추적 시스템을 사용해야하고 데이터를 추적해야합니까? 내가 알아야 할 기존 패러다임이 있습니까?
* 재설정되지 않습니다. * 2^32 또는 2^64 씩 증가합니다. 일명 'time_t' 2038 호^_^ – Shepmaster
@Shepmaster : 예, 저는 64 비트 카운터가 1 단위 씩 오버플로 할 수 없기 때문에'AtomicU64 '가 안정적 이었으면합니다. (수학적 경향에 대해서는 600 년이 걸립니다. 1 inc/ns, 또는 5 GHz에서 ~ 120 년)로 오버 플로우됩니다. –
나는 원자 적재를'wait()'에 넣을 수 있었고 재로드 된 카운트가 더 높을 때 쓰레드가 깨어났다. – xrl