0

我有一个在 do while 循环中运行的 while 循环。我需要 while 循环准确地每秒运行一次,不快也不慢。但我不确定我会怎么做。这是循环,在它自己的函数中关闭。我听说过 sleep() 函数,但我也听说它不是很准确。

int min5()
{
    int second = 00;
    int minute = 0;
    const int ZERO = 00;

    do{
        while (second <= 59){
        if(minute == 5) break;
        second += 1;
        if(second == 60) minute += 1;
        if(second == 60) second = ZERO;
        if(second < 60) cout << "Current Time> "<< minute <<" : "<< second <<" \n";
        }
      } while (minute <= 5);
}
4

5 回答 5

4

您可以达到的最佳准确度是使用操作系统 (OS) 功能。您需要找到也具有回调函数的 API。回调函数是您编写的一个函数,当计时器到期时操作系统将调用该函数。

请注意,由于程序执行时正在运行的其他任务和活动,操作系统可能会失去计时精度。

于 2010-05-04T18:57:26.407 回答
3

如果您想要一个可移植的解决方案,您不应该期望高精度时序。通常,您只能通过依赖于平台的解决方案来获得它。

一个可移植的(尽管 CPU 效率不是很高,也不是特别优雅)的解决方案可能会使用类似于以下的函数:

#include <ctime>

void wait_until_next_second()
{
    time_t before = time(0);
    while (difftime(time(0), before) < 1);
}

然后你会在你的函数中使用它,如下所示:

int min5()
{
    wait_until_next_second();  // synchronization (optional), so that the first
                               // subsequent call will not take less than 1 sec.
    ...
    do
    {
        wait_until_next_second();  // waits approx. one second
        while (...)
        {
            ...
        }
    } while (...)
}

对您的代码的一些进一步评论:

  • minute一旦达到值 5,您的代码就会进入无限循环。

  • 您是否知道00表示八进制(基数 8)数(由于前导零)?在这种情况下没关系,但要小心数字,例如017. 这是十进制的 15,而不是 17!

  • 您可以将seconds++权利合并到while循环的条件中:while (seconds++ <= 59) ...

  • 我认为在这种情况下,最好插入endlcout流中,因为这会刷新它,而插入"\n"不会刷新流。在这里并不重要,但您的意图似乎是始终查看当前时间cout;如果您不刷新流,则实际上并不能保证立即看到时间消息。

于 2010-05-04T19:09:15.503 回答
1

正如其他人发布的那样,您的操作系统可能会提供某种警报或计时器功能。您应该尝试使用这种东西,而不是编写自己的轮询循环。轮询时间意味着您需要每秒切换一次上下文,这样可以在系统可以执行其他操作时保持代码运行。在这种情况下,您打断别人 300 次只是为了说“我们完成了吗”。

此外,你永远不应该对睡眠的持续时间做出假设——即使你有一个实时操作系统,这也是不安全的——你应该总是询问实时时钟或滴答计数器每次已经过去了多少时间,否则任何错误都会累积所以随着时间的推移,你会变得越来越不准确。即使在实时系统上也是如此,因为即使实时系统可以准确地休眠 1 秒,您的代码也需要一些时间才能运行,因此这种计时错误会在每次通过循环时累积。

于 2010-05-04T19:08:32.573 回答
1

例如,在 Windows 中,可以创建一个可等待的计时器对象。

如果那是您的操作系统,请检查此处的文档,例如Waitable Timer Objects

从您提供的代码看来,您尝试做的事情可以通过睡眠更轻松地完成。保证您的循环体每 1 秒执行一次是没有意义的。而是让它每秒执行 10 次,并检查从最后一次经过的时间,你采取了一些行动,是否超过一秒。如果没有,什么也不做。如果是,请采取行动(打印您的消息,增加变量等),存储最后一次行动的时间并再次循环。

于 2010-05-04T19:04:51.240 回答
0
Sleep(1000);

http://msdn.microsoft.com/en-us/library/ms686298(VS.85).aspx

于 2010-05-04T18:55:53.930 回答