Метод wait_for
Метод wait_for класса condition_variable блокирует текущий поток до момента пробуждения от уведомления или до истечения указанного времени ожидания. В первый параметр мы передаём объект unique_lock, который должен быть заблокирован текущим потоком. Во второй параметр мы передаём промежуток времени, в течение которого поток будет ожидать. В третий необязательный параметр мы передаём предикат - функцию, возвращающую bool, которая проверяет условие пробуждения.
Метод возвращает std::cv_status::timeout, если истекло время ожидания, или std::cv_status::no_timeout, если поток был разбужен уведомлением. Если задан предикат, метод возвращает bool - результат последней проверки предиката.
Синтаксис
cv.wait_for(lock, rel_time);
cv.wait_for(lock, rel_time, pred);
Пример
Давайте создадим поток, который ждёт уведомления не более 100 миллисекунд. Если уведомление не придёт, метод вернёт std::cv_status::timeout:
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>
using namespace std;
int main()
{
mutex mtx;
condition_variable cv;
unique_lock<mutex> lock(mtx);
cv_status status = cv.wait_for(lock, chrono::milliseconds(100));
if (status == cv_status::timeout) {
cout << "timeout" << endl;
} else {
cout << "notified" << endl;
}
return 0;
}
Результат выполнения кода:
"timeout"
Пример
Давайте создадим поток, который уведомит ожидающий поток раньше истечения времени ожидания:
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>
using namespace std;
int main()
{
mutex mtx;
condition_variable cv;
unique_lock<mutex> lock(mtx);
thread t([&cv, &mtx]() {
this_thread::sleep_for(chrono::milliseconds(50));
lock_guard<mutex> lg(mtx);
cv.notify_one();
});
cv_status status = cv.wait_for(lock, chrono::milliseconds(500));
if (status == cv_status::timeout) {
cout << "timeout" << endl;
} else {
cout << "notified" << endl;
}
t.join();
return 0;
}
Результат выполнения кода:
"notified"
Пример
Давайте используем предикат, чтобы метод возвращал bool. Поток будет ждать, пока флаг не станет true, но не более 200 миллисекунд:
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>
using namespace std;
int main()
{
mutex mtx;
condition_variable cv;
bool ready = false;
unique_lock<mutex> lock(mtx);
thread t([&cv, &mtx, &ready]() {
this_thread::sleep_for(chrono::milliseconds(100));
lock_guard<mutex> lg(mtx);
ready = true;
cv.notify_one();
});
bool res = cv.wait_for(lock, chrono::milliseconds(500), [&ready]() {
return ready;
});
cout << boolalpha << res << endl;
t.join();
return 0;
}
Результат выполнения кода:
true
Смотрите также
-
метод
wait,
который блокирует поток до уведомления -
метод
notify_one,
который будит один ожидающий поток -
класс
condition_variable,
который синхронизирует потоки по условию -
класс
unique_lock,
который управляет блокировкой мьютекса