Метод wait
Метод wait класса Condvar блокирует текущий поток,
пока другой поток не вызовет notify_one или notify_all.
Параметром метод принимает мьютекс, который должен быть захвачен
до вызова метода. Во время ожидания мьютекс освобождается,
позволяя другим потокам изменять защищённые данные. Когда поток
просыпается, мьютекс снова захватывается. Метод возвращает
LockResult с мьютекс-гардом.
Синтаксис
condvar.wait(guard)
Пример
Давайте рассмотрим простой пример, где один поток ожидает уведомления от другого потока:
use std::sync::{Arc, Mutex, Condvar};
use std::thread;
fn main()
{
let pair = Arc::new((Mutex::new(false), Condvar::new()));
let pair2 = Arc::clone(&pair);
let handle = thread::spawn(move || {
let (lock, cvar) = &*pair2;
let mut started = lock.lock().unwrap();
*started = true;
cvar.notify_one();
});
let (lock, cvar) = &*pair;
let mut started = lock.lock().unwrap();
while !*started {
started = cvar.wait(started).unwrap();
}
println!("Поток получил уведомление");
handle.join().unwrap();
}
Результат выполнения кода:
"Поток получил уведомление"
Пример
Давайте рассмотрим пример с несколькими потоками, которые ожидают уведомления от главного потока:
use std::sync::{Arc, Mutex, Condvar};
use std::thread;
fn main()
{
let pair = Arc::new((Mutex::new(false), Condvar::new()));
let mut handles = vec![];
for i in 0..3 {
let pair = Arc::clone(&pair);
let handle = thread::spawn(move || {
let (lock, cvar) = &*pair;
let mut started = lock.lock().unwrap();
while !*started {
started = cvar.wait(started).unwrap();
}
println!("Поток {} получил уведомление", i);
});
handles.push(handle);
}
thread::sleep(std::time::Duration::from_millis(100));
let (lock, cvar) = &*pair;
let mut started = lock.lock().unwrap();
*started = true;
cvar.notify_all();
drop(started);
for handle in handles {
handle.join().unwrap();
}
}
Результат выполнения кода:
"Поток 0 получил уведомление"
"Поток 1 получил уведомление"
"Поток 2 получил уведомление"
Смотрите также
-
класс
Condvar,
который представляет условную переменную для синхронизации потоков -
метод
new,
который создаёт новую условную переменную -
метод
notify_one,
который пробуждает один ожидающий поток -
метод
notify_all,
который пробуждает все ожидающие потоки