c++ - 在 C++ 中每 n 秒调用一次函数的最有效方法是什么?

标签 c++

所以我尝试每 n 秒调用一个函数。以下是我要实现的目标的简单表示。我想知道下面的方法是否是实现此目的的唯一方法。如果可以避免“如果”条件,我会很高兴。

#include <stdio.h>
#include <time.h>

void print_hello(int i) {
  printf("hello\n");
  printf("%d\n", i);
}

int main () {
   time_t start_t, end_t;
   double diff_t;

   time(&start_t);

   int i = 0;

   while(1) {
     time(&end_t);
     // printf("here in main");

     i = i + 1;
     diff_t = difftime(end_t, start_t);
     if(diff_t==5) {
        // printf("Execution time = %f\n", diff_t);
        print_hello(i);
        time(&start_t);
     }
   }

   return(0);
}

最佳答案

OPs 程序中时间的使用可以减少为类似

// get tStart;
// set tEnd = tStart + x;
do {
  // get t;
} while (t < tEnd);

这就是所谓的busy-wait .

它可用于编写具有最精确计时的代码以及其他特殊情况。缺点是等待会消耗大量 CPU 负载。 (您甚至可以通过提高通风噪音听到这一点。)

In general, however, spinning is considered an anti-pattern and should be avoided, as processor time that could be used to execute a different task is instead wasted on useless activity.

另一种选择是将唤醒委托(delegate)给系统,这样可以在等待时将进程/线程的负载降至最低:

#include <chrono>
#include <iostream>
#include <thread>

void print_hello(int i)
{
  std::cout << "hello\n"
    << i << '\n';
}

int main ()
{
  using namespace std::chrono_literals; // to support e.g. 5s for 5 sceconds

  auto tStart = std::chrono::system_clock::now();
  for (int i = 1; i <= 3; ++i) {
    auto tEnd = tStart + 2s;
    std::this_thread::sleep_until(tEnd);
    print_hello(i);
    tStart = tEnd;
  }
}

输出:

hello
1
hello
2
hello
3

Live Demo on coliru

(我不得不减少迭代次数和等待时间以防止在线编译器中出现 TLE。)

std::this_thread::sleep_until

Blocks the execution of the current thread until specified sleep_time has been reached.

The clock tied to sleep_time is used, which means that adjustments of the clock are taken into account. Thus, the duration of the block might, but might not, be less or more than sleep_time - Clock::now() at the time of the call, depending on the direction of the adjustment. The function also may block for longer than until after sleep_time has been reached due to scheduling or resource contention delays.

最后一句话提到了这个解决方案的缺点:操作系统可能决定在请求之后唤醒线程/进程。这可能会发生,例如操作系统是否处于高负载状态。在“正常”情况下,延迟不应超过几毫秒。因此,延迟可能是可以容忍的。

请注意 tEndtStart 是如何循环更新的。不考虑当前唤醒时间以防止延迟累积。

关于c++ - 在 C++ 中每 n 秒调用一次函数的最有效方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57840379/

相关文章:

c++ - 向数组添加维度

c++ - 动态规划——求数组中的目标求和方式

c++ - 从 void * 转换为 Local<Function>

C++函数原型(prototype)?

c++ - C++中sizeof运算符的操作

c++ - 快板 5 al_draw_textf()

c++ - IsDebuggerPresent() 函数是停止调试进程的安全方法吗?

c++ - swscaler 错误的 src 图像指针

c++ - QCalendarWidget - 如何禁用日期

c++ - boost::asio::deadline_timer 绑定(bind)到多态套接字类指针