std::condition_variable:: wait_for
|
template
<
class
Rep,
class
Period
>
std::
cv_status
wait_for
(
std::
unique_lock
<
std::
mutex
>
&
lock,
|
(1) | (начиная с C++11) |
|
template
<
class
Rep,
class
Period,
class
Predicate
>
bool
wait_for
(
std::
unique_lock
<
std::
mutex
>
&
lock,
|
(2) | (начиная с C++11) |
wait_for
приводит к блокировке текущего потока до тех пор, пока не будет получено уведомление от переменной условия, не истечет заданный промежуток времени или не произойдет ложное пробуждение.
pred
может быть опционально предоставлен для обнаружения ложных пробуждений.
Сразу после возврата из
wait_for
,
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 | - | блокировка, которая должна быть захвачена вызывающим потоком |
| rel_time | - | максимальное время ожидания |
| pred | - | предикат для проверки возможности завершения ожидания |
| Требования к типам | ||
-
Predicate
должен удовлетворять требованиям
FunctionObject
.
|
||
|
-
|
||
Возвращаемое значение
Исключения
Примечания
Даже при уведомлении под блокировкой, перегрузка (1) не дает никаких гарантий относительно состояния связанного предиката при возврате из-за таймаута.
Эффекты
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 2093 | C++11 | исключения, связанные с таймаутом, отсутствовали в спецификации | упоминает эти исключения |
|
LWG 2114
( P2167R3 ) |
C++11 | конвертируемость в bool была слишком слабой для отражения ожиданий реализаций | требования усилены |
| LWG 2135 | C++11 | поведение было неясным, если lock. lock ( ) выбрасывает исключение | вызывает std::terminate в этом случае |
Смотрите также
|
блокирует текущий поток до тех пор, пока условная переменная не будет пробуждена
(public member function) |
|
|
блокирует текущий поток до тех пор, пока условная переменная не будет пробуждена или не будет достигнута указанная точка времени
(public member function) |