Struct std::sync::Condvar

1.0.0 · source ·
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();
}
Run

Implementations§

source§

impl Condvar

const: 1.63.0 · source

pub const fn new() -> Condvar

创建一个新的条件变量,可以随时等待它并通知它。

Examples
use std::sync::Condvar;

let condvar = Condvar::new();
Run
source

pub fn wait<'a, T>( &self, guard: MutexGuard<'a, T> ) -> LockResult<MutexGuard<'a, T>>

阻塞当前线程,直到此条件变量收到通知为止。

该函数将自动解锁指定的互斥锁 (由 guard 表示) 并阻塞当前线程。 这意味着在互斥锁解锁后逻辑上发生的任何对 notify_onenotify_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();
}
Run
1.42.0 · source

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_onenotify_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();
Run
source

pub 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

等待此条件变量以获取通知,并在指定的持续时间后超时。

该函数的语义与 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
    }
}
Run
1.5.0 · source

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
    }
}
Run
1.42.0 · source

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 访问锁定的互斥锁
Run
source

pub fn notify_one(&self)

在此 condvar 上唤醒一个阻塞的线程。

如果此条件变量上有阻塞的线程,则它将从其调用中唤醒到 waitwait_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();
}
Run
source

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

Trait Implementations§

1.16.0 · source§

impl Debug for Condvar

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

使用给定的格式化程序格式化该值。 Read more
1.10.0 · source§

impl Default for Condvar

source§

fn default() -> Condvar

创建一个 Condvar,可以等待它并通知它。

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

获取 selfTypeIdRead more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

从拥有的值中一成不变地借用。 Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

从拥有的值中借用。 Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

返回未更改的参数。

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

调用 U::from(self)

也就是说,这种转换是 From<T> for U 实现选择执行的任何操作。

source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

发生转换错误时返回的类型。
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

执行转换。
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

发生转换错误时返回的类型。
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

执行转换。