std::condition_variable:: wait
|
void
wait
(
std::
unique_lock
<
std::
mutex
>
&
lock
)
;
|
(1) | (начиная с C++11) |
|
template
<
class
Predicate
>
void wait ( std:: unique_lock < std:: mutex > & lock, Predicate pred ) ; |
(2) | (начиная с C++11) |
wait
блокирует текущий поток до тех пор, пока не будет получено уведомление от условной переменной или не произойдет ложное пробуждение.
pred
может быть опционально предоставлен для обнаружения ложных пробуждений.
wait ( lock ) ; .
Сразу после возврата из
wait
,
lock.
owns_lock
(
)
имеет значение
true
, и
lock.
mutex
(
)
заблокирован вызывающим потоком. Если эти постусловия не могут быть выполнены
[1]
, вызывается
std::terminate
.
Если выполняется любое из следующих условий, поведение не определено:
- lock. owns_lock ( ) равно false .
- lock. mutex ( ) не заблокирован вызывающим потоком.
-
Если другие потоки также ожидают на
*
this
,
lock.
mutex
(
)
отличается от мьютекса, разблокированного функциями ожидания (
wait, wait_for и wait_until ), вызванными на * this этими потоками.
- ↑ Это может произойти, если повторная блокировка мьютекса вызывает исключение.
Содержание |
Параметры
| lock | - | блокировка, которая должна быть захвачена вызывающим потоком |
| pred | - | предикат для проверки возможности завершения ожидания |
| Требования к типам | ||
-
Predicate
должен удовлетворять требованиям
FunctionObject
.
|
||
|
-
|
||
Исключения
Примечания
Эффекты
notify_one()
/
notify_all()
и каждой из трёх атомарных частей
wait()
/
wait_for()
/
wait_until()
(разблокировка+ожидание, пробуждение и блокировка) происходят в едином полном порядке, который можно рассматривать как
порядок модификации
атомарной переменной: этот порядок специфичен для данной конкретной переменной условия. Это делает невозможным, чтобы
notify_one()
, например, был задержан и разблокировал поток, который начал ожидание сразу после вызова
notify_one()
.
Пример
#include <chrono> #include <condition_variable> #include <iostream> #include <thread> std::condition_variable cv; std::mutex cv_m; // Этот мьютекс используется для трёх целей: // 1) для синхронизации доступа к i // 2) для синхронизации доступа к std::cerr // 3) для переменной условия cv int i = 0; void waits() { std::unique_lock<std::mutex> lk(cv_m); std::cerr << "Waiting... \n"; cv.wait(lk, []{ return i == 1; }); std::cerr << "...finished waiting. i == 1\n"; } void signals() { std::this_thread::sleep_for(std::chrono::seconds(1)); { std::lock_guard<std::mutex> lk(cv_m); std::cerr << "Notifying...\n"; } cv.notify_all(); std::this_thread::sleep_for(std::chrono::seconds(1)); { std::lock_guard<std::mutex> lk(cv_m); i = 1; std::cerr << "Notifying again...\n"; } cv.notify_all(); } int main() { std::thread t1(waits), t2(waits), t3(waits), t4(signals); t1.join(); t2.join(); t3.join(); t4.join(); }
Возможный вывод:
Waiting... Waiting... Waiting... Notifying... Notifying again... ...finished waiting. i == 1 ...finished waiting. i == 1 ...finished waiting. i == 1
Отчеты о дефектах
Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Применяется к | Поведение в опубликованной версии | Корректное поведение |
|---|---|---|---|
|
LWG 2114
( P2167R3 ) |
C++11 | конвертируемость в bool была слишком слабой для отражения ожиданий реализаций | требования усилены |
| LWG 2135 | C++11 | поведение было неясным, если lock. lock ( ) выбрасывает исключение | вызывает std::terminate в этом случае |
Смотрите также
|
блокирует текущий поток до пробуждения переменной условия или после указанной длительности таймаута
(public member function) |
|
|
блокирует текущий поток до пробуждения переменной условия или до достижения указанной точки времени
(public member function) |
|
|
C documentation
для
cnd_wait
|
|
Внешние ссылки
| The Old New Thing статья: Ложные пробуждения в условных переменных Win32. |