std::condition_variable_any:: wait_until
|
template
<
class
Lock,
class
Clock,
class
Duration
>
std::
cv_status
|
(1) | (начиная с C++11) |
|
template
<
class
Lock,
class
Clock,
class
Duration,
class
Predicate
>
bool
wait_until
(
Lock
&
lock,
|
(2) | (начиная с C++11) |
|
template
<
class
Lock,
class
Clock,
class
Duration,
class
Predicate
>
bool
wait_until
(
Lock
&
lock,
std::
stop_token
stoken,
|
(3) | (начиная с C++20) |
wait_until
приводит к блокировке текущего потока до тех пор, пока не будет получено уведомление от переменной условия, не истечет указанный промежуток времени или не произойдет ложное пробуждение.
pred
может быть опционально предоставлен для обнаружения ложных пробуждений.
if ( wait_until ( lock, abs_time ) == std:: cv_status :: timeout )
return pred ( ) ;
return true ; .
{
if ( pred ( ) )
return true ;
if ( wait_until ( lock, abs_time ) == std:: cv_status :: timeout )
return pred ( ) ;
}
return pred ( ) ; .
Сразу после того, как
wait_until
возвращает управление,
lock
блокируется вызывающим потоком. Если это постусловие не может быть выполнено
[1]
, вызывается
std::terminate
.
- ↑ Это может произойти, если повторная блокировка мьютекса вызывает исключение.
Содержание |
Параметры
| lock | - | блокировка, которая должна быть захвачена вызывающим потоком |
| stoken | - | токен остановки для регистрации прерывания |
| abs_time | - | точка времени, когда ожидание истекает |
| pred | - | предикат для проверки возможности завершения ожидания |
| Требования к типам | ||
-
Lock
должен удовлетворять требованиям
BasicLockable
.
|
||
-
Predicate
должен удовлетворять требованиям
FunctionObject
.
|
||
|
-
|
||
Возвращаемое значение
Исключения
Примечания
Стандарт рекомендует использовать часы, связанные с
abs_time
для измерения времени; эти часы не обязаны быть монотонными. Не дается никаких гарантий относительно поведения этой функции при дискретной корректировке часов, но существующие реализации преобразуют
abs_time
из
Clock
в
std::chrono::system_clock
и делегируют вызов POSIX-функции
pthread_cond_timedwait
, чтобы ожидание учитывало корректировки системных часов, но не пользовательских
Clock
. В любом случае, функция также может ожидать дольше, чем до момента достижения
abs_time
из-за задержек планирования или конкуренции за ресурсы.
Даже если используемые часы являются std::chrono::steady_clock или другим монотонным clock, корректировка системного clock может вызвать ложное пробуждение.
Эффекты
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_any 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) |
|
|
wait_until
|
блокирует текущий поток до тех пор, пока условная переменная не будет активирована или не будет достигнута указанная точка времени
(public member function) |