РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
1078 of 1245 menu

Класс Condvar

Класс Condvar (condition variable) представляет собой примитив синхронизации, который позволяет блокировать выполнение одного или нескольких потоков до тех пор, пока другой поток не уведомит их о наступлении определённого события. Условная переменная всегда используется совместно с мьютексом Mutex, который защищает общие данные. Метод new создаёт новую условную переменную, метод wait блокирует текущий поток и освобождает мьютекс, а методы notify_one и notify_all пробуждают один или все ожидающие потоки соответственно.

Синтаксис

use std::sync::{Condvar, Mutex}; let pair = (Mutex::new(value), Condvar::new());

Пример

Давайте создадим условную переменную вместе с мьютексом и посмотрим на базовое ожидание и уведомление:

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 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(); } handle.join().unwrap(); println!("{}", *started); }

Результат выполнения кода:

true

Пример

Давайте используем метод wait_timeout, чтобы поток не ждал уведомления бесконечно:

use std::sync::{Arc, Condvar, Mutex}; use std::time::Duration; fn main() { let pair = Arc::new((Mutex::new(false), Condvar::new())); let (lock, cvar) = &*pair; let started = lock.lock().unwrap(); let (res, timeout) = cvar .wait_timeout(started, Duration::from_millis(100)) .unwrap(); println!("{}", *res); println!("{}", timeout.timed_out()); }

Результат выполнения кода:

false true

Пример

Давайте используем метод notify_all, чтобы разбудить сразу несколько ожидающих потоков:

use std::sync::{Arc, Condvar, Mutex}; use std::thread; fn main() { let pair = Arc::new((Mutex::new(0), Condvar::new())); let mut handles = vec![]; for _ in 0..3 { let pair = Arc::clone(&pair); handles.push(thread::spawn(move || { let (lock, cvar) = &*pair; let mut count = lock.lock().unwrap(); while *count == 0 { count = cvar.wait(count).unwrap(); } *count })); } let (lock, cvar) = &*pair; let mut count = lock.lock().unwrap(); *count = 42; cvar.notify_all(); drop(count); for handle in handles { println!("{}", handle.join().unwrap()); } }

Результат выполнения кода:

42 42 42

Смотрите также

  • метод new,
    который создаёт новую условную переменную
  • метод wait,
    который блокирует поток до получения уведомления
  • метод wait_timeout,
    который блокирует поток на указанное время
  • метод notify_one,
    который пробуждает один ожидающий поток
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить