C ++如何每10秒检查一次时间?

时间:2013-04-22 08:27:32

标签: c++ time

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

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

5 个答案:

答案 0 :(得分:9)

如果您是新手程序员,那么非常简短的答案就是非常困难

现在有几个可能性:

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

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

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

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

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

这并不容易。


这是一个切线,可能是有启发性的。基本上有两种计算机程序(除了所有其他类型):

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

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

直到你明白如何做 nothing ,你才能设计出第二种程序。

答案 1 :(得分:3)

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

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

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

sleep(10);

答案 2 :(得分: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
}

答案 3 :(得分:0)

您可以在程序中使用事件循环并安排计时器进行回调。 For example您可以使用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有自己的事件循环,所以你可以使用它们。

答案 4 :(得分: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()不是很准确。如果您需要更高精度的时序(即优于10ms的分辨率),您可能需要深入挖掘。此外,使用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));
}