pub struct Condvar { /* private fields */ }
Expand description
条件变量
条件变量表示阻塞线程的能力,以使线程在等待事件发生时不占用任何 CPU 时间。 条件变量通常与布尔谓词 (条件) 和互斥锁相关联。 在确定线程必须阻塞之前,始终在互斥锁内部验证该谓词。
此模块中的函数将阻止当前的执行线程。 请注意,对同一条件变量使用多个互斥锁的任何尝试都可能导致运行时 panic。
Examples
use std::sync::{Arc, Mutex, Condvar};
use std::thread;
let pair = Arc::new((Mutex::new(false), Condvar::new()));
let pair2 = Arc::clone(&pair);
// 在我们的锁内部,spawn 有一个新线程,然后等待它启动。
thread::spawn(move|| {
let (lock, cvar) = &*pair2;
let mut started = lock.lock().unwrap();
*started = true;
// 我们通知 condvar 值已更改。
cvar.notify_one();
});
// 等待线程启动。
let (lock, cvar) = &*pair;
let mut started = lock.lock().unwrap();
while !*started {
started = cvar.wait(started).unwrap();
}
RunImplementations§
source§impl Condvar
impl Condvar
sourcepub fn wait<'a, T>(
&self,
guard: MutexGuard<'a, T>
) -> LockResult<MutexGuard<'a, T>>
pub fn wait<'a, T>( &self, guard: MutexGuard<'a, T> ) -> LockResult<MutexGuard<'a, T>>
阻塞当前线程,直到此条件变量收到通知为止。
该函数将自动解锁指定的互斥锁 (由 guard
表示) 并阻塞当前线程。
这意味着在互斥锁解锁后逻辑上发生的任何对 notify_one
或 notify_all
的调用都可以唤醒该线程。
当此函数调用返回时,将重新获得指定的锁。
请注意,此函数易受虚假唤醒的影响。 条件变量通常具有与之关联的布尔谓词,并且每次此函数返回时都必须始终检查谓词,以防止虚假唤醒。
Errors
如果正在等待的互斥锁在此线程重新获取锁时中毒,则此函数将返回错误。
有关更多信息,请参见有关 Mutex
类型的 中毒 的信息。
Panics
如果长时间使用此函数与多个互斥锁,则该函数可能为 panic!
。
Examples
use std::sync::{Arc, Mutex, Condvar};
use std::thread;
let pair = Arc::new((Mutex::new(false), Condvar::new()));
let pair2 = Arc::clone(&pair);
thread::spawn(move|| {
let (lock, cvar) = &*pair2;
let mut started = lock.lock().unwrap();
*started = true;
// 我们通知 condvar 值已更改。
cvar.notify_one();
});
// 等待线程启动。
let (lock, cvar) = &*pair;
let mut started = lock.lock().unwrap();
// 只要 `Mutex<bool>` 内部的值为 `false`,我们就等待。
while !*started {
started = cvar.wait(started).unwrap();
}
Run1.42.0 · sourcepub fn wait_while<'a, T, F>(
&self,
guard: MutexGuard<'a, T>,
condition: F
) -> LockResult<MutexGuard<'a, T>>where
F: FnMut(&mut T) -> bool,
pub fn wait_while<'a, T, F>( &self, guard: MutexGuard<'a, T>, condition: F ) -> LockResult<MutexGuard<'a, T>>where F: FnMut(&mut T) -> bool,
阻止当前线程,直到此条件变量接收到通知并且所提供的条件为 false 为止。
该函数将自动解锁指定的互斥锁 (由 guard
表示) 并阻塞当前线程。
这意味着在互斥锁解锁后逻辑上发生的任何对 notify_one
或 notify_all
的调用都可以唤醒该线程。
当此函数调用返回时,将重新获得指定的锁。
Errors
如果正在等待的互斥锁在此线程重新获取锁时中毒,则此函数将返回错误。
有关更多信息,请参见有关 Mutex
类型的 中毒 的信息。
Examples
use std::sync::{Arc, Mutex, Condvar};
use std::thread;
let pair = Arc::new((Mutex::new(true), Condvar::new()));
let pair2 = Arc::clone(&pair);
thread::spawn(move|| {
let (lock, cvar) = &*pair2;
let mut pending = lock.lock().unwrap();
*pending = false;
// 我们通知 condvar 值已更改。
cvar.notify_one();
});
// 等待线程启动。
let (lock, cvar) = &*pair;
// 只要 `Mutex<bool>` 内部的值为 `true`,我们就等待。
let _guard = cvar.wait_while(lock.lock().unwrap(), |pending| { *pending }).unwrap();
Runsourcepub fn wait_timeout_ms<'a, T>(
&self,
guard: MutexGuard<'a, T>,
ms: u32
) -> LockResult<(MutexGuard<'a, T>, bool)>
👎Deprecated since 1.6.0: replaced by std::sync::Condvar::wait_timeout
pub fn wait_timeout_ms<'a, T>( &self, guard: MutexGuard<'a, T>, ms: u32 ) -> LockResult<(MutexGuard<'a, T>, bool)>
std::sync::Condvar::wait_timeout
等待此条件变量以获取通知,并在指定的持续时间后超时。
该函数的语义与 wait
等效,除了线程被阻塞的时间大约不超过 ms
毫秒。
由于抢占或平台差异等异常情况可能不会导致最大等待时间精确到 ms
,因此不应将此方法用于精确计时。
请注意,已尽最大努力确保使用单调时钟来测量等待的时间,并且不受系统时间更改的影响。
仅当已知超时已经过去时,返回的布尔值为 false
。
与 wait
一样,无论是否经过超时,都将在此函数返回时重新获取指定的锁。
Examples
use std::sync::{Arc, Mutex, Condvar};
use std::thread;
let pair = Arc::new((Mutex::new(false), Condvar::new()));
let pair2 = Arc::clone(&pair);
thread::spawn(move|| {
let (lock, cvar) = &*pair2;
let mut started = lock.lock().unwrap();
*started = true;
// 我们通知 condvar 值已更改。
cvar.notify_one();
});
// 等待线程启动。
let (lock, cvar) = &*pair;
let mut started = lock.lock().unwrap();
// 只要 `Mutex<bool>` 内部的值为 `false`,我们就等待。
loop {
let result = cvar.wait_timeout_ms(started, 10).unwrap();
// 10 毫秒已过去,或者值已更改!
started = result.0;
if *started == true {
// 我们已收到通知,并且值已更新,我们可以离开。
break
}
}
Run1.5.0 · sourcepub fn wait_timeout<'a, T>(
&self,
guard: MutexGuard<'a, T>,
dur: Duration
) -> LockResult<(MutexGuard<'a, T>, WaitTimeoutResult)>
pub fn wait_timeout<'a, T>( &self, guard: MutexGuard<'a, T>, dur: Duration ) -> LockResult<(MutexGuard<'a, T>, WaitTimeoutResult)>
等待此条件变量以获取通知,并在指定的持续时间后超时。
该函数的语义与 wait
等效,除了线程被阻塞的时间不超过 dur
。
由于抢占或平台差异等异常情况可能不会导致最大等待时间精确到 dur
,因此不应将此方法用于精确计时。
请注意,已尽最大努力确保使用单调时钟来测量等待的时间,并且不受系统时间更改的影响。
此函数易受虚假唤醒的影响。
条件变量通常具有与之关联的布尔谓词,并且每次此函数返回时都必须始终检查谓词,以防止虚假唤醒。
另外,尽管有虚假的唤醒,但通常还是希望超时不超过某个持续时间,因此睡眠时间会减少睡眠量。
或者,在谓词为 true 时,使用 wait_timeout_while
方法等待超时。
返回的 WaitTimeoutResult
值指示是否已知超时。
与 wait
一样,无论是否经过超时,都将在此函数返回时重新获取指定的锁。
Examples
use std::sync::{Arc, Mutex, Condvar};
use std::thread;
use std::time::Duration;
let pair = Arc::new((Mutex::new(false), Condvar::new()));
let pair2 = Arc::clone(&pair);
thread::spawn(move|| {
let (lock, cvar) = &*pair2;
let mut started = lock.lock().unwrap();
*started = true;
// 我们通知 condvar 值已更改。
cvar.notify_one();
});
// 等待线程启动
let (lock, cvar) = &*pair;
let mut started = lock.lock().unwrap();
// 只要 `Mutex<bool>` 内的值为 `false`,我们就等待
loop {
let result = cvar.wait_timeout(started, Duration::from_millis(10)).unwrap();
// 10 毫秒已过去,或者值已更改!
started = result.0;
if *started == true {
// 我们已收到通知,并且值已更新,我们可以离开。
break
}
}
Run1.42.0 · sourcepub fn wait_timeout_while<'a, T, F>(
&self,
guard: MutexGuard<'a, T>,
dur: Duration,
condition: F
) -> LockResult<(MutexGuard<'a, T>, WaitTimeoutResult)>where
F: FnMut(&mut T) -> bool,
pub fn wait_timeout_while<'a, T, F>( &self, guard: MutexGuard<'a, T>, dur: Duration, condition: F ) -> LockResult<(MutexGuard<'a, T>, WaitTimeoutResult)>where F: FnMut(&mut T) -> bool,
等待此条件变量以获取通知,并在指定的持续时间后超时。
该函数的语义与 wait_while
等效,除了线程被阻塞的时间不超过 dur
。
由于抢占或平台差异等异常情况可能不会导致最大等待时间精确到 dur
,因此不应将此方法用于精确计时。
请注意,已尽最大努力确保使用单调时钟来测量等待的时间,并且不受系统时间更改的影响。
返回的 WaitTimeoutResult
值指示是否已知超时已经过去,而没有满足条件。
与 wait_while
一样,无论是否经过超时,都将在此函数返回时重新获取指定的锁。
Examples
use std::sync::{Arc, Mutex, Condvar};
use std::thread;
use std::time::Duration;
let pair = Arc::new((Mutex::new(true), Condvar::new()));
let pair2 = Arc::clone(&pair);
thread::spawn(move|| {
let (lock, cvar) = &*pair2;
let mut pending = lock.lock().unwrap();
*pending = false;
// 我们通知 condvar 值已更改。
cvar.notify_one();
});
// 等待线程启动
let (lock, cvar) = &*pair;
let result = cvar.wait_timeout_while(
lock.lock().unwrap(),
Duration::from_millis(100),
|&mut pending| pending,
).unwrap();
if result.1.timed_out() {
// 超时,条件永远不会为 false。
}
// 通过 result.0 访问锁定的互斥锁
Runsourcepub fn notify_one(&self)
pub fn notify_one(&self)
在此 condvar 上唤醒一个阻塞的线程。
如果此条件变量上有阻塞的线程,则它将从其调用中唤醒到 wait
或 wait_timeout
。
不会以任何方式缓冲对 notify_one
的调用。
要唤醒所有线程,请参见 notify_all
。
Examples
use std::sync::{Arc, Mutex, Condvar};
use std::thread;
let pair = Arc::new((Mutex::new(false), Condvar::new()));
let pair2 = Arc::clone(&pair);
thread::spawn(move|| {
let (lock, cvar) = &*pair2;
let mut started = lock.lock().unwrap();
*started = true;
// 我们通知 condvar 值已更改。
cvar.notify_one();
});
// 等待线程启动。
let (lock, cvar) = &*pair;
let mut started = lock.lock().unwrap();
// 只要 `Mutex<bool>` 内部的值为 `false`,我们就等待。
while !*started {
started = cvar.wait(started).unwrap();
}
Runsourcepub fn notify_all(&self)
pub fn notify_all(&self)
唤醒此 condvar 上的所有阻塞线程。
此方法将确保唤醒条件变量上的所有当前侍者。
不会以任何方式缓冲对 notify_all()
的调用。
要仅唤醒一个线程,请参见 notify_one
。
Examples
use std::sync::{Arc, Mutex, Condvar};
use std::thread;
let pair = Arc::new((Mutex::new(false), Condvar::new()));
let pair2 = Arc::clone(&pair);
thread::spawn(move|| {
let (lock, cvar) = &*pair2;
let mut started = lock.lock().unwrap();
*started = true;
// 我们通知 condvar 值已更改。
cvar.notify_all();
});
// 等待线程启动。
let (lock, cvar) = &*pair;
let mut started = lock.lock().unwrap();
// 只要 `Mutex<bool>` 内部的值为 `false`,我们就等待。
while !*started {
started = cvar.wait(started).unwrap();
}
Run