Есть ли стандартная функция для занятого ожидания условия или до истечения времени ожидания
Мне нужно ждать в моей программе для подсистемы. В разных местах приходится ждать разных условий. Я знаю, что мог бы также использовать переменные потоков и условий. Но так как подсистема (запрограммированная в C на "голом железе") подключена через разделяемую память без прерываний, зарегистрированных в ней - один поток все равно должен опрашивать.
Поэтому я сделал следующий шаблон, чтобы иметь возможность ждать чего угодно. Мне было интересно, есть ли уже функция STL, которая может быть использована для этого?
#include <chrono>
#include <thread>
//given poll interval
template<typename predicate,
typename Rep1, typename Period1,
typename Rep2, typename Period2>
bool waitActiveFor(predicate check,
std::chrono::duration<Rep1, Period1> x_timeout,
std::chrono::duration<Rep2, Period2> x_pollInterval)
{
auto x_start = std::chrono::steady_clock::now();
while (true)
{
if (check())
return true;
if ((std::chrono::steady_clock::now() - x_start) > x_timeout)
return false;
std::this_thread::sleep_for(x_pollInterval);
}
}
//no poll interval defined
template<typename predicate,
typename Rep, typename Period>
bool waitActiveFor(predicate check,
std::chrono::duration<Rep, Period> x_timeout)
{
auto x_start = std::chrono::steady_clock::now();
while (true)
{
if (check())
return true;
if ((std::chrono::steady_clock::now() - x_start) > x_timeout)
return false;
std::this_thread::yield();
}
}
2019-05-23: обновление кода в отношении комментариев и ответов
2 ответа
Не в моих знаниях. В общем, цель состоит в том, чтобы ждать без записи тактов, поэтому стандартная библиотека ориентирована на это использование.
Я в курсе std::this_thread::yield()
это то, что я обычно использую, когда я хочу ждать ожидания, но так как у вас есть интервал опроса, sleep_for()
это, вероятно, ваш лучший выбор.
Есть ли стандартная функция для занятого ожидания условия или до истечения времени ожидания
Нет. Есть функции для блокировки до тайм-аута или уведомления, но не для занятого ожидания. Однако это действительно довольно просто написать, как вы продемонстрировали.
Важное соображение относительно контекста: в целом нет никаких гарантий, что check()
все еще true после того, как функция возвратила true. Чтобы добиться этой гарантии, вы должны убедиться, что все, что касается общей памяти (включая подсистему), не изменит проверку на ложь, за исключением потока, который выполняет опрос (и это означает, что может быть только один). нить делаю так).
Обзор бонусного кода
- Так как у вас в любом случае есть шаблон, возможно, хорошей идеей будет также задавать тип временных аргументов, чтобы пользователь мог использовать любой
std::chrono::time_point
и тем самым любая единица желание. Кроме того, вы можете избавиться отduration_cast
с иcount
в вашем шаблоне.