std:: condition_variable
|
Определено в заголовочном файле
<condition_variable>
|
||
|
class
condition_variable
;
|
(начиная с C++11) | |
std::condition_variable
— это примитив синхронизации, используемый вместе с
std::mutex
для блокировки одного или нескольких потоков до тех пор, пока другой поток не изменит общую переменную (
условие
) и не уведомит
std::condition_variable
.
Поток, который намерен изменить общую переменную, должен:
- Получите std::mutex (обычно через std::lock_guard ).
- Измените общую переменную, пока блокировка удерживается.
-
Вызовите
notify_one
или
notify_all
на
std::condition_variable(может быть выполнено после освобождения блокировки).
Даже если общая переменная является атомарной, она должна быть изменена при владении мьютексом, чтобы корректно опубликовать изменение в ожидающий поток.
Любой поток, который намеревается ожидать на
std::condition_variable
должен:
- Получите std:: unique_lock < std:: mutex > на мьютексе, используемом для защиты общей переменной.
- Выполните одно из следующих действий:
-
- Проверьте условие, на случай если оно уже было обновлено и уведомлено.
-
Вызовите
wait
,
wait_for
, или
wait_until
на
std::condition_variable(атомарно освобождает мьютекс и приостанавливает выполнение потока до тех пор, пока не будет получено уведомление от переменной условия, не истечет таймаут, или не произойдет ложное пробуждение , затем атомарно захватывает мьютекс перед возвратом). - Проверьте условие и возобновите ожидание, если оно не удовлетворено.
- или:
- Используйте перегруженную версию с предикатом для wait , wait_for , и wait_until , которая выполняет те же три шага.
std::condition_variable
работает только с
std::
unique_lock
<
std::
mutex
>
, что позволяет достичь максимальной эффективности на некоторых платформах.
std::condition_variable_any
предоставляет переменную условия, которая работает с любым объектом
BasicLockable
, таким как
std::shared_lock
.
Условные переменные позволяют параллельный вызов wait , wait_for , wait_until , notify_one и notify_all функций-членов.
Класс
std::condition_variable
является
StandardLayoutType
. Он не является
CopyConstructible
,
MoveConstructible
,
CopyAssignable
или
MoveAssignable
.
Содержание |
Вложенные типы
| Название | Определение |
native_handle_type
|
определяется реализацией |
Функции-члены
|
конструирует объект
(public member function) |
|
|
уничтожает объект
(public member function) |
|
|
operator=
[deleted]
|
не копируемый
(public member function) |
Уведомление |
|
|
уведомляет один ожидающий поток
(public member function) |
|
|
уведомляет все ожидающие потоки
(public member function) |
|
Ожидание |
|
|
блокирует текущий поток до пробуждения переменной условия
(public member function) |
|
|
блокирует текущий поток до пробуждения переменной условия или после указанной длительности таймаута
(public member function) |
|
|
блокирует текущий поток до пробуждения переменной условия или до достижения указанной точки времени
(public member function) |
|
Нативный дескриптор |
|
|
возвращает нативный дескриптор
(public member function) |
|
Пример
std::condition_variable
используется в комбинации с
std::mutex
для обеспечения межпоточного взаимодействия.
#include <condition_variable> #include <iostream> #include <mutex> #include <string> #include <thread> std::mutex m; std::condition_variable cv; std::string data; bool ready = false; bool processed = false; void worker_thread() { // ожидание, пока main() отправит данные std::unique_lock lk(m); cv.wait(lk, []{ return ready; }); // после ожидания мы владеем блокировкой std::cout << "Worker thread is processing data\n"; data += " after processing"; // отправка данных обратно в main() processed = true; std::cout << "Worker thread signals data processing completed\n"; // ручная разблокировка выполняется до уведомления, чтобы избежать пробуждения // ожидающего потока только для повторной блокировки (см. notify_one для подробностей) lk.unlock(); cv.notify_one(); } int main() { std::thread worker(worker_thread); data = "Example data"; // отправка данных в рабочий поток { std::lock_guard lk(m); ready = true; std::cout << "main() signals data ready for processing\n"; } cv.notify_one(); // ожидание рабочего потока { std::unique_lock lk(m); cv.wait(lk, []{ return processed; }); } std::cout << "Back in main(), data = " << data << '\n'; worker.join(); }
Вывод:
main() signals data ready for processing Worker thread is processing data Worker thread signals data processing completed Back in main(), data = Example data after processing
Смотрите также
|
(C++11)
|
предоставляет переменную условия, ассоциированную с любым типом блокировки
(класс) |
|
(C++11)
|
предоставляет базовое средство взаимного исключения
(класс) |
|
(C++11)
|
реализует строго ограниченную по области обёртку владения мьютексом
(шаблон класса) |
|
(C++11)
|
реализует перемещаемую обёртку владения мьютексом
(шаблон класса) |