C++ 中的延迟循环输出

发布于 2024-08-31 10:54:49 字数 559 浏览 4 评论 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);
}

I have a while loop that runs in a do while loop. I need the while loop to run exactly every second no faster no slower. but i'm not sure how i would do that. this is the loop, off in its own function. I have heard of the sleep() function but I also have heard that it is not very accurate.

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);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

软糯酥胸 2024-09-07 10:54:49

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

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

The best accuracy you can achieve is by using Operating System (OS) functions. You need to find the API that also has a callback function. The callback function is a function you write that the OS will call when the timer has expired.

Be aware that the OS may lose timing precision due to other tasks and activities that are running while your program is executing.

沫离伤花 2024-09-07 10:54:49

如果您想要便携式解决方案,则不应期望高精度计时。通常,您只能通过依赖于平台的解决方案来实现这一点。

一个可移植的(尽管 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 (...)
}

一些进一步的评论在您的代码上:

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

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

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

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

If you want a portable solution, you shouldn't expect high-precision timing. Usually, you only get that with a platform-dependent solution.

A portable (albeit not very CPU-efficient, nor particularly elegant) solution might make use of a function similar to this:

#include <ctime>

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

You'd then use this in your function like this:

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 (...)
}

Some further comments on your code:

  • Your code gets into an endless loop once minute reaches the value 5.

  • Are you aware that 00 denotes an octal (radix 8) number (due to the leading zero)? It doesn't matter in this case, but be careful with numbers such as 017. This is decimal 15, not 17!

  • You could incorporate the seconds++ right into the while loop's condition: while (seconds++ <= 59) ...

  • I think in this case, it would be better to insert endl into the cout stream, since that will flush it, while inserting "\n" won't flush the stream. It doesn't truly matter here, but your intent seems to be to always see the current time on cout; if you don't flush the stream, you're not actually guaranteed to see the time message immediately.

番薯 2024-09-07 10:54:49

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

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

As someone else posted, your OS may provide some kind of alarm or timer functionality. You should try to use this kind of thing rather than coding your own polling loop. Polling the time means you need to be context switched in every second, which keeps your code running when the system could be doing other stuff. In this case you interrupt someone else 300 times just to say "are we done yet".

Also, you should never make assumptions about the duration of a sleep - even if you had a real time OS this would be unsafe - you should always ask the real time clock or tick counter how much time has elapsed each time because otherwise any errors accumulate so you will get less and less accurate over time. This is true even on a real time system because even if a real time system could sleep accurately for 1 second, it takes some time for your code to run so this timing error would accumulate on each pass through the loop.

月棠 2024-09-07 10:54:49

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

如果这是您的操作系统,请检查此处的文档,例如 等待计时器对象

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

In Windows for example, there is a possibility to create a waitable timer object.

If that's Your operating system check the documentation here for example Waitable Timer Objects.

From the code You presented it looks like what You are trying to do can be done much easier with sleep. It doesn't make sense to guarantee that Your loop body is executed exactly every 1 second. Instead make it execute 10 times a second and check if the time that elapsed form the last time, You took some action, is more than a second or not. If not, do nothing. If yes, take action (print Your message, increment variables etc), store the time of last action and loop again.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文