2010-05-04 3 views
0

У меня есть цикл while, который работает в цикле do 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 секунду. sleep() - ваш лучший вариант. Он позволяет ОС решать, как наилучшим образом задерживать, как можно ближе к указанному интервалу. –

+0

Какая операционная система? –

+1

Какая точность вам нужна? Сон, скорее всего, будет достаточно хорошим, основываясь на коде, который вы здесь показываете. –

ответ

4

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

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

0
+0

Если * dwMilliseconds * меньше разрешения системных часов, поток может спать менее указанного периода времени. –

+0

Как вы знаете, что OP использует Windows в качестве платформы? BTW, другие платформы имеют методы «сна». Ссылка может не помочь, если OP использует Linux или Mac или встроенную систему. –

+0

@Thomas Matthews Я знаю, что это для окон, и я не был уверен, что OP его использует.я решил сделать предположение :) – Andrey

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

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

+0

О, я не знал. до этого момента я самоучтен, вот почему мой код выглядит уродливым XD, пока я не попал в колледж. Я учился в основном из-за ошибок, таких как это, поэтому еще раз спасибо за помощь (^_^) – itachisxeyes

+1

@itachisxeyes: Я не имел в виду, что ваш код уродлив. Я видел, что вы отметили свой вопрос «начинающим», поэтому я подумал, что дам вам дополнительные намеки на некоторые вещи, которые вы можете сделать с вашим кодом. Надеюсь, это не принесло вам какого-либо преступления; это, конечно, не мое намерение. – stakx

+0

О, я не принял никакого нарушения, я просто предполагаю, что большинство всего, что я пишу, является уродливым и, вероятно, может быть сделано лучше и эффективнее. и благодарю вас, когда дополнительная миля с дополнительной помощью. – itachisxeyes

Смежные вопросы