Здравствуйте, astlin, Вы писали:
A>Я вижу грубое решение наподобие:
A>A> int time_left = N; // период в секундах
A> for (;;) {
A> Thread::sleep(time_left*1000); // Засыпаем до следующего периода
A> Timestamp starting_time; // Время запуска задачи
A> RunTask();
A> Timestamp ending_time; // Время окончания задачи
A> int diff = ending_time - starting_time; // время выполнения в микросекундах
A> time_left = N * 1000 - diff / 1000; // Вычисляем время спячки
A> }
A>
A> Но смущают возникшие задачи по корректировке времени. Вопрос: есть ли более точный и изящный путь запускать задачу каждые N секунд без сдвигов и т.п.?
Так ты быстро накопишь ошибку...
Точнее будет привязываться к определенным моментам времени
int nexttime = time() + N;
for (;;)
{
Thread::sleep(nexttime - time());
RunTask();
nexttime += N;
}
Добрый день!
Есть тривиальная задача запускать некую процедуру раз в N секунд, примерно так:
for(;;) {
Thread::sleep(N*1000);
RunTask();
}
Однако, выполение процедуры занимает какое-то время M (M<N) и т.о. время запуска процедуры сдвигается на M+N+время затраченное на возврат в начало цикла.
Я вижу грубое решение наподобие:
int time_left = N; // период в секундах
for (;;) {
Thread::sleep(time_left*1000); // Засыпаем до следующего периода
Timestamp starting_time; // Время запуска задачи
RunTask();
Timestamp ending_time; // Время окончания задачи
int diff = ending_time - starting_time; // время выполнения в микросекундах
time_left = N * 1000 - diff / 1000; // Вычисляем время спячки
}
Но смущают возникшие задачи по корректировке времени. Вопрос: есть ли более точный и изящный путь запускать задачу каждые N секунд без сдвигов и т.п.?
Здравствуйте, astlin, Вы писали:
A>A> int time_left = N; // период в секундах
A> for (;;) {
A> Thread::sleep(time_left*1000); // Засыпаем до следующего периода
A> Timestamp starting_time; // Время запуска задачи
A> RunTask();
A> Timestamp ending_time; // Время окончания задачи
A> int diff = ending_time - starting_time; // время выполнения в микросекундах
A> time_left = N * 1000 - diff / 1000; // Вычисляем время спячки
A> }
A>
A> Но смущают возникшие задачи по корректировке времени. Вопрос: есть ли более точный и изящный путь запускать задачу каждые N секунд без сдвигов и т.п.?
Ну, во-первых, такой тип таймера (стабильный due rate) обычно делается чуть не так — в памяти держится время следующего срабатывания, после срабатывания плюсуется интервал и по нему вычисляется время ожидания. Таким образом не будет плыть время срабатывания.
Иногда при этом также поддерживают по выравниванию на конкретное время (например, в пределах 7-й минуты каждого часа).
Далее, Вы твёрдо уверены, что нужен именно вариант постоянной частоты срабатывания? Для многих случаев таки лучше применять нефиксированный, с выдерживаемым промежутком от конца предыдущей отработки до начала следующей.
Про конкретные стандартные средства нельзя говорить, пока не указана платформа.
Здравствуйте, astlin, Вы писали:
A> Есть тривиальная задача запускать некую процедуру раз в N секунд, примерно так:
A>A> for(;;) {
A> Thread::sleep(N*1000);
A> RunTask();
A> }
A>
Если Windows, то можно использовать CreateWaitableTimer/SetWaitableTimer/WaitForSinlgeObject. См. MSDN.