2010-05-04 210 views
0

我有一个运行在do while循环中的while循环。我需要while循环正好每秒运行不会更快,也不会更慢。但我不知道我会怎么做。这是循环,关闭它自己的功能。我听说过sleep()函数,但我也听说它不是很准确。C++中的延迟循环输出

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

大多数操作系统都不是实时操作系统。您无法每次都获得精确的1秒分辨率。睡眠()是你最好的选择。它让操作系统决定如何最好地延迟,尽可能接近指定的时间间隔。 – 2010-05-04 18:57:45

+0

什么操作系统? – 2010-05-04 18:58:09

+1

你需要什么样的准确性?基于你在这里展示的代码,睡眠很可能足够好。 – 2010-05-04 19:00:22

回答

4

可以达到最佳精度是通过操作系统(OS)的功能。您需要找到同样具有回调函数的API。 回调函数是您编写的一个函数,当定时器到期时OS将调用该函数。

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

0
+0

如果* dwMilliseconds *小于系统时钟的分辨率,则线程可能会睡眠时间小于指定的时间长度。 – 2010-05-04 18:57:33

+0

您如何知道OP使用Windows作为平台?顺便说一句,其他平台有'睡眠'方法。如果OP使用Linux或Mac或嵌入式系统,链接可能无法帮助。 – 2010-05-04 18:58:43

+0

@Thomas Matthews我知道它是用于Windows,我不确定OP是否在使用它。我决定做一个猜测:) – Andrey 2010-05-04 19:02:30

1

例如,在Windows中,可能会创建一个等待定时器对象。

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

从代码您提出它看起来像你试图做的事情可以做更容易睡眠。确保您的循环体每1秒精确执行一次没有意义。取而代之的是让它每秒执行10次,并检查上一次过去的时间,你采取了一些行动,超过一秒钟。如果没有,什么都不要做。如果是的话,采取行动(打印你的信息,增加变量等),存储最后一次行动的时间并再次循环。

1

作为其他人发布的,您的操作系统可能会提供某种警报或计时器功能。你应该尝试使用这种类型的东西,而不是编码自己的轮询循环。轮询时间意味着您需要在每秒钟进行上下文切换,这可以让系统在执行其他任务时继续运行代码。在这种情况下,你打断其他人300次只是说“我们还没有完成”。另外,你永远不应该对睡眠持续时间做出假设 - 即使你有一个实时操作系统,这将是不安全的 - 你应该总是询问实时时钟或滴答计数器每次有多少时间已经过去,因为否则任何错误都会累积,所以随着时间的推移,你会越来越不准确。即使在实时系统中也是如此,因为即使实时系统能够准确地睡眠1秒,您的代码也需要一段时间才能运行,因此每次通过循环时都会累积该时间误差。

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;如果你不刷新流,你实际上并不保证立即看到时间消息。

+0

哦,我不知道。直到这一点我自学,这就是为什么我的代码看起来很难看XD所以直到我进入大学我一直在这样的错误主要是学习,所以再次感谢您的帮助(^_^) – itachisxeyes 2010-05-04 19:20:46

+1

@itachisxeyes:我并不是说你的代码很丑。我看到你用'beginner'标记了你的问题,所以我想我会给你一些你可以用你的代码做的事情的提示。我希望这不会给你任何罪行;那当然不是我的意图。 – stakx 2010-05-04 20:10:38

+0

哦,我没有采取任何进攻,我只是假设我写的大部分内容都很难看,可能会做得更好,效率更高。 并且当额外的帮助时,我很感激你。 – itachisxeyes 2010-05-05 03:48:34