2

我正在写一个检查点。每次运行循环时我都会检查。我认为这会浪费大量的 CPU 时间。我想知道如何每 10 秒检查一次系统时间?

time_t start = clock();
while(forever)
{
    if(difftime(clock(),start)/CLOCKS_PER_SEC >=timeLimit)
    {
        break;
    }
}
4

5 回答 5

9

非常简短的回答是,如果您是新手程序员,这非常困难。

现在有几个可能性:

  • 睡十秒钟。这意味着您的程序基本上没有意义。

  • 使用alarm()和信号处理程序。这很难做到正确,因为您不能在信号处理程序中做任何花哨的事情。

  • 使用 atimerfd并将时序逻辑集成到您的 I/O 循环中。

  • 为定时器设置一个专用线程(然后可以休眠);这非常困难,因为您需要考虑同步所有共享数据访问。

这里要带回家的一点是,您的问题没有简单的解决方案。您需要将时序逻辑深入集成到您现有的程序流程中。该流程应该是某种“主循环”(例如,像epoll_waitor的 I/O 多路复用循环select),可能是多线程的,并且该循环应该获取计时器已触发的事实。

那并没那么简单。


这是一个切线,可能具有指导意义。基本上有两种计算机程序(除了所有其他类型):

一种是尽可能高效地执行一项特定任务然后完成的程序。例如,这类似于“生成 SSL 密钥对”或“查找文件中与 X 匹配的所有行”。就程序流程而言,这些是易于编写和理解的程序。

另一种是与用户交互的程序。这些程序无限期地停留并响应用户输入。(基本上任何类型的 UI 或游戏,但也包括 Web 服务器。)从控制流的角度来看,这些程序大部分时间都在做......什么都不做。他们只是空闲等待用户输入。因此,当您考虑如何对此进行编程时,如何使程序什么都不做?这是“主循环”的核心:它是一个循环,它告诉操作系统让进程保持睡眠状态,直到发生有趣的事情,然后处理有趣的事件,然后重新进入睡眠状态。

直到您了解如何什么都不做,您才能设计第二种程序。

于 2013-04-22T08:32:40.100 回答
3

如果您需要精度,您可以使用 null 参数调用 select() 但有延迟。这精确到毫秒。

struct timeval timeout= {10, 0};
select(1,NULL,NULL,NULL, &timeout);

如果你不这样做,只需使用 sleep():

sleep(10);
于 2013-04-22T08:32:35.693 回答
0

最简单的方法(在单线程环境中)是休眠一段时间并反复检查总等待时间是否已过期。

int sleepPeriodMs = 500;
time_t start = clock();
while(forever)
{
    while(difftime(clock(),start)/CLOCKS_PER_SEC <timeLimit) // NOTE: Change of logic here!
    {
        sleep(sleepPeriod);
    }
}

请注意,这sleep()不是很准确。如果您需要更高精度的计时(即分辨率优于 10 毫秒),您可能需要更深入地挖掘。此外,对于 C++11,还有<chrono>提供更多功能的标头。

using namespace std::chrono;

int sleepPeriodMs = 500;
time_t start = clock();
while(forever)
{
    auto start = system_clock()::now()
    // do some stuff that takes between [0..10[ seconds
    std::this_thread::sleep_until(start+seconds(10));
}
于 2013-04-22T08:36:20.367 回答
0

您可以在程序中使用事件循环并安排计时器进行回调。例如,您可以使用libev制作事件循环并添加计时器。

   ev_timer_init (timer, callback, 0., 5.);
   ev_timer_again (loop, timer);
   ...
   timer->again = 17.;
   ev_timer_again (loop, timer);
   ...
   timer->again = 10.;
   ev_timer_again (loop, timer);

如果您在特定工具包中编写代码,则可以使用其他事件循环,gtk、qt、glib 有自己的事件循环,因此您可以使用它们。

于 2013-04-22T08:34:25.637 回答
0

只需添加一个sleep调用即可为系统提供 CPU 时间:

time_t start = clock();
while(forever)
{
    if(difftime(clock(),start)/CLOCKS_PER_SEC >=timeLimit)
    {
        break;
    }
    sleep(1); // <<< put process to sleep for 1s
}
于 2013-04-22T08:29:09.157 回答