Есть ли стандартная функция для занятого ожидания условия или до истечения времени ожидания - PullRequest
1 голос
/ 22 мая 2019

Мне нужно ждать в моей программе подсистемы.В разных местах приходится ждать разных условий.Я знаю, что мог бы также использовать переменные потоков и условий.Но так как подсистема (запрограммированная в 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 ]

1 голос
/ 22 мая 2019

Есть ли стандартная функция для занятого ожидания условия или до истечения времени ожидания

Нет. Существуют функции для блокировки до истечения времени ожидания или уведомления, но не для занят ожидания. Однако это действительно довольно просто написать, как вы продемонстрировали.

Важное соображение относительно контекста: в целом, нет гарантии, что check() все еще имеет значение true после того, как функция вернула true. Чтобы добиться этой гарантии, вы должны убедиться, что все, что касается общей памяти (включая подсистему), не изменит проверку на ложь, за исключением потока, который выполняет опрос (и это означает, что может быть только один). нить так).


Отзыв о бонусном коде

  • Так как у вас есть шаблон в любом случае, вероятно, будет хорошей идеей также разрешить тип временных аргументов, чтобы пользователь мог использовать любой std::chrono::time_point и, следовательно, любую единицу по желанию. Кроме того, вы можете избавиться от duration_cast s и count в вашем шаблоне.
1 голос
/ 22 мая 2019

Не в моих силах.В общем, цель состоит в том, чтобы ждать без записи тактов, поэтому стандартная библиотека ориентирована на это использование.

Мне известно о std::this_thread::yield(), которое я обычно использую, когда хочу занятого ожидания,но так как у вас есть интервал опроса, sleep_for(), вероятно, является вашей лучшей ставкой.

...