Метод notify_one
Метод notify_one класса Condvar пробуждает
один поток, который в данный момент ожидает на этом
условном переменном (то есть находится в вызове метода
wait или wait_timeout). Если несколько
потоков ожидают пробуждения, метод выберет только один
из них, при этом какой именно поток будет разбужен -
не детерминировано и зависит от реализации операционной
системы. Если на момент вызова ни один поток не ожидает,
уведомление не сохраняется и не будет доставлено
позже. Метод не принимает параметров и не возвращает
значения.
Синтаксис
condvar.notify_one()
Пример
Давайте рассмотрим пример, в котором главный поток
устанавливает флаг готовности и будит один из ожидающих
потоков с помощью notify_one:
use std::sync::{Arc, Condvar, Mutex};
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 ready = lock.lock().unwrap();
while !*ready {
ready = cvar.wait(ready).unwrap();
}
println!("thread woke up");
});
let (lock, cvar) = &*pair;
let mut ready = lock.lock().unwrap();
*ready = true;
cvar.notify_one();
drop(ready);
handle.join().unwrap();
}
Результат выполнения кода:
"thread woke up"
Пример
Давайте рассмотрим пример, в котором два потока ожидают
на одном условном переменном, а главный поток будит
только один из них через notify_one:
use std::sync::{Arc, Condvar, Mutex};
use std::thread;
fn main()
{
let pair = Arc::new((Mutex::new(false), Condvar::new()));
let mut handles = Vec::new();
for i in 1..=2 {
let pair = Arc::clone(&pair);
let handle = thread::spawn(move || {
let (lock, cvar) = &*pair;
let mut ready = lock.lock().unwrap();
while !*ready {
ready = cvar.wait(ready).unwrap();
}
println!("thread {} woke up", i);
});
handles.push(handle);
}
thread::sleep(std::time::Duration::from_millis(100));
let (lock, cvar) = &*pair;
let mut ready = lock.lock().unwrap();
*ready = true;
cvar.notify_one();
drop(ready);
for handle in handles {
handle.join().unwrap();
}
}
Результат выполнения кода (один из потоков может остаться заблокированным, так как уведомление получает только один поток):
"thread 1 woke up"
Смотрите также
-
класс
Condvar,
который представляет условную переменную для синхронизации потоков -
метод
wait,
который блокирует поток до получения уведомления -
метод
wait_timeout,
который блокирует поток на заданное время или до уведомления -
метод
notify_all,
который пробуждает все ожидающие потоки