Table of Contents generated with DocToc
condition var 条件变量代表阻止线程的能力,使其在等待事件发生时不消耗CPU时间。 在其他语言中也有类似的概念,叫做栅栏,闭锁,屏障,信号量等。他们具有相同的意义。
在介绍条件变量之前,先介绍屏障(Barrier)。屏障相当于一堵带门的墙,使用wait方法,在某个点阻塞全部进入临界区的线程。条件变量(Condition Variable)和屏障的语义类似,但它不是阻塞全部线程,而是在满足某些特定条件之前阻塞某一个得到互斥锁的线程
- CondVar需要和锁一起使用,在运行中每个条件变量每次只可以和一个互斥体一起使用。
这个接口需要一个 MutexGuard,以便于知道需要唤醒哪个 Mutex 下等待的线程.
推荐使用 parking_lot的实现。 parking_lot的设计精髓在于其自适应的锁机制。在无竞争状态下,锁的获取和释放仅需一次原子操作; 微竞争时,会进行几次循环尝试,而不是立即挂起线程;当竞争激烈时,线程会在尝试一段时间后被暂停,避免过度消耗CPU资源。 此外,该库还支持硬件锁消除,进一步提高了读取密集型任务的性能
// parking_lot-0.12.3/src/condvar.rs
impl Condvar {
#[inline]
pub fn wait<T: ?Sized>(&self, mutex_guard: &mut MutexGuard<'_, T>) {
self.wait_until_internal(unsafe { MutexGuard::mutex(mutex_guard).raw() }, None);
}
}
- 超小的存储开销:Mutex和Once只需要1字节,而Condvar和RwLock只占1个机器字。
- 快速无竞争和快速释放:单次原子操作完成。
- 微竞争优化:自适应循环尝试。
- 硬件锁消除:对于具备硬件支持的处理器,提升读性能。
- 可选的死锁检测:实验性特性,需开启deadlock_detection。
- 支持序列化(serde):通过启用serde特性。
- 可发送的锁守卫:通过启用send_guard特性。
- 平均公平性:避免长时间等待。
- 递归锁:通过ReentrantMutex类型实现