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

时间:2019-05-22 16:15:03

标签: c++ busy-waiting busy-loop

我需要在程序中等待子系统。在不同的地方必须等待不同的条件。我知道我也可以利用线程和条件变量。但是由于子系统(用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();
  }
}

running sample


2019-05-23:有关注释和答案的代码更新

2 个答案:

答案 0 :(得分:1)

据我所知。通常,目标是在不消耗时钟周期的情况下等待,因此标准库适用于该用法。

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

答案 1 :(得分:1)

  

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

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

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


奖金代码审查

  • 由于总有一个模板,最好也对时间参数的类型进行模板化,以便用户可以使用任何std::chrono::time_point并由此使用任何单位。另外,您可以在模板中摆脱duration_castcount的影响。