2013-04-22 2 views
2

Я пишу контрольный пункт. Я проверяю каждый раз, когда я запускаю цикл. Я думаю, что это потеряет много процессорного времени. Интересно, как проверять системное время каждые 10 секунд?C++ как проверить время каждые 10 секунд?

time_t start = clock(); 
while(forever) 
{ 
    if(difftime(clock(),start)/CLOCKS_PER_SEC >=timeLimit) 
    { 
     break; 
    } 
} 
+0

Создайте себе тему и определите какой-то обратный вызов. –

+0

Сон может быть использован, но я не знаю, это то, что вы хотите. –

+2

Это как функция отсрочки на будильниках и мобильных телефонах в сочетании с ленивой природой программистов смены кладбища. 'start:' Тревога. F ** k, все еще сонный. * Snooze * ... * Через несколько минут * 'goto start;'. –

ответ

9

Очень короткий ответ, что это очень трудно , если вы начинающий программист.

Теперь несколько possiblilites:

  • сна в течение десяти секунд. Это означает, что ваша программа в основном бессмысленна.

  • Использование alarm() и обработчиков сигналов. Это сложно сделать правильно, потому что вы не должны ничего делать в обработчике сигналов.

  • Используйте timerfd и интегрируйте логику синхронизации в свою схему ввода/вывода.

  • Настроить выделенный поток для таймера (который затем может спать); это чрезвычайно сложно, потому что вам нужно подумать о синхронизации общего доступа к данным.

Точка зрения, чтобы забрать домой здесь, состоит в том, что ваша проблема не имеет простого решения. Вам необходимо глубоко интегрировать логику синхронизации в уже существующий программный поток. Этот поток должен быть своего рода «основным циклом» (например, циклом мультиплексирования ввода-вывода, например epoll_wait или select), возможно многопоточным, и этот цикл должен учитывать тот факт, что таймер был запущен.

Это не так просто.


Вот тангенс, возможно, поучительный. Существуют, в основном, два вида компьютерной программы (кроме всех других видов):

Один вид программ, которые выполняют одну конкретную задачу, насколько это возможно, и затем выполняются. Это, например, нечто вроде «генерации пары ключей SSL» или «найти все строки в файле, который соответствует X». Это те программы, которые легко писать и понимать в отношении потока программы.

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

Пока вы не поймете, как сделать ничего, что вы сможете проектировать программы второго рода.

+1

Основной трюк в этой второй программе спрашивает ОС: «Что происходит?». ОС не ответит на этот вопрос сразу, но только тогда, когда у него есть реальный ответ. – MSalters

+0

Я на самом деле делаю программу MPI, поэтому я должен пожертвовать одним процессором, чтобы делать часы? это будет лучший ответ? – weeo

+0

@weeo: Это не только о CPU (и, конечно, время процессора процессора было бы незначительным, так как сон является бесплатным). Но многопоточный дизайн более сложный, поэтому лично я остался бы однопоточным (epoll + timerfd) до тех пор, насколько это возможно ... но это зависит от вашего дизайна! Может быть, отдельная, спальная нить точно подходит вам ... –

0

Просто добавьте вызов sleep, чтобы дать процессорное время в системе:

time_t start = clock(); 
while(forever) 
{ 
    if(difftime(clock(),start)/CLOCKS_PER_SEC >=timeLimit) 
    { 
     break; 
    } 
    sleep(1); // <<< put process to sleep for 1s 
} 
3

Если вам нужна точность, вы можете поместить вызов для выбора() с нулевыми параметрами, но с задержкой. Это точно до миллисекунды.

struct timeval timeout= {10, 0}; 
select(1,NULL,NULL,NULL, &timeout); 

Если вы не просто использовать сон():

sleep(10); 
0

Вы можете использовать цикл событий в своей программе и настроить таймер для выполнения обратного вызова. For example вы можете использовать libev, чтобы создать цикл событий и добавить таймер.

ev_timer_init (timer, callback, 0., 5.); 
    ev_timer_again (loop, timer); 
    ... 
    timer->again = 17.; 
    ev_timer_again (loop, timer); 
    ... 
    timer->again = 10.; 
    ev_timer_again (loop, timer); 

Если код в определенном инструментарии вы можете использовать другие циклы событий, GTK, Qt, бойкий имеет собственное событие петли, так что вы можете использовать их.

0

Простейший подход (в однопоточной среде) должен был бы спать некоторое время и многократно проверять, истекло ли общее время ожидания.

int sleepPeriodMs = 500; 
time_t start = clock(); 
while(forever) 
{ 
    while(difftime(clock(),start)/CLOCKS_PER_SEC <timeLimit) // NOTE: Change of logic here! 
    { 
     sleep(sleepPeriod); 
    } 
} 

Обратите внимание, что sleep() не очень точен. Если вам нужна более высокая точность (т. Е. Лучше, чем 10 мс разрешения), вам может понадобиться копать глубже. Кроме того, с C++ 11 есть заголовок <chrono>, который предлагает гораздо больше функциональности.

using namespace std::chrono; 

int sleepPeriodMs = 500; 
time_t start = clock(); 
while(forever) 
{ 
    auto start = system_clock()::now() 
    // do some stuff that takes between [0..10[ seconds 
    std::this_thread::sleep_until(start+seconds(10)); 
} 
Смежные вопросы