вывод цикла задержки в C ++ - PullRequest
0 голосов
/ 04 мая 2010

У меня есть цикл while, который выполняется в цикле do 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);
}

Ответы [ 5 ]

4 голосов
/ 04 мая 2010

Наилучшая точность, которую вы можете достичь, это использование функций операционной системы (ОС). Вам нужно найти API, который также имеет функцию callback . Функция callback - это написанная вами функция, которую ОС будет вызывать по истечении таймера.

Помните, что ОС может потерять точность синхронизации из-за других задач и действий, выполняемых во время выполнения вашей программы.

3 голосов
/ 04 мая 2010

Если вы хотите портативное решение, вы не должны ожидать высокой точности синхронизации. Обычно вы получаете это только в зависимости от платформы.

Переносимое (хотя и не слишком эффективное для ЦП, но и не особо элегантное) решение может использовать функцию, подобную этой:

#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) ...

  • Я думаю, что в этом случае было бы лучше вставить endl в поток cout, так как это очистит его, а вставка "\n" не очистит поток. Здесь это не имеет значения, но ваше намерение, похоже, всегда видеть текущее время на cout; если вы не очистите поток, вы не гарантированно сразу увидите сообщение о времени.

1 голос
/ 04 мая 2010

Как уже сообщал кто-то, ваша ОС может обеспечивать некоторые функции будильника или таймера. Вы должны попытаться использовать такого рода вещи, а не кодировать свой собственный цикл опроса. Опрос времени означает, что вам необходимо переключать контекст каждую секунду, что позволяет вашему коду работать, когда система может делать другие вещи. В этом случае вы перебиваете кого-то еще 300 раз, просто чтобы сказать «мы уже закончили».

Кроме того, вы никогда не должны делать предположений о продолжительности сна - даже если у вас была ОС реального времени, это было бы небезопасно - вы всегда должны спрашивать часы реального времени или счетчик тиков, сколько времени прошло каждый раз, потому что в противном случае любые ошибки накапливаются, поэтому вы будете получать все меньше и меньше точности с течением времени. Это верно даже для системы реального времени, потому что даже если система реального времени может бездействовать точно в течение 1 секунды, вашему коду требуется некоторое время, чтобы эта ошибка синхронизации накапливалась при каждом проходе цикла.

1 голос
/ 04 мая 2010

В Windows, например, есть возможность создать ожидаемый объект таймера.

Если это Ваша операционная система, проверьте документацию здесь, например Объекты ожидаемого таймера .

Из кода, который вы представили, похоже, что то, что вы пытаетесь сделать, можно сделать намного проще с помощью сна. Нет смысла гарантировать, что тело вашего цикла выполняется ровно каждую 1 секунду. Вместо этого заставьте его выполняться 10 раз в секунду и проверьте, прошло ли время, прошедшее с последнего раза, Вы предприняли какое-то действие, больше секунды или нет. Если нет, ничего не делай. Если да, выполните действие (распечатайте ваше сообщение, увеличьте переменные и т. Д.), Сохраните время последнего действия и повторите цикл.

0 голосов
/ 04 мая 2010
...