1

我需要在我的程序中等待子系统。在不同的地方一个必须等​​待不同的条件。我知道我也可以使用线程和条件变量。但是由于子系统(用 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:关于评论和答案的代码更新

4

2 回答 2

1

是否有标准功能忙于等待条件或直到超时

不,有阻塞直到超时或通知的功能,但没有等待的功能。但是,正如您所展示的那样,这确实很容易编写。

关于上下文的一个重要考虑因素:通常不能保证check()函数返回 true 后仍然为 true。为了实现这一保证,您必须确保任何接触共享内存(包括子系统)的东西都不会将检查更改为假,执行轮询的线程除外(这意味着只能有一个线程这样做)。


奖励代码审查

  • 既然你有一个模板,最好让时间参数的类型也被模板化,这样用户就可以使用任何std::chrono::time_point单位,从而可以使用任何单位。此外,您可以在模板中去掉duration_casts 和count
于 2019-05-22T17:18:16.300 回答
1

据我所知不是。一般来说,目标是在不消耗时钟周期的情况下等待,因此标准库是针对这种用法的。

我知道std::this_thread::yield()当我想忙等待时我通常使用哪个,但是由于您有轮询间隔,sleep_for()因此可能是您最好的选择。

于 2019-05-22T16:23:26.650 回答