2010-10-22 5 views
2

Я использую компилятор GCC и C++, и я хочу сделать таймер, который вызывает прерывание, когда обратный отсчет равен 0.Как реализовать таймер с прерыванием в C++?

Любые идеи? Заранее спасибо.

EDIT

Благодаря Адаму, я знаю, как это сделать.

Теперь. Как насчет нескольких таймеров, работающих параллельно?

На самом деле, эти таймеры предназначены для чего-то очень простого. В NCURSES у меня есть список вещей. Когда я нажимаю клавишу, одна из вещей изменит цвета на 5 секунд. Если я нажму другую клавишу, другая вещь в списке сделает то же самое. Это как подчеркивание строк в зависимости от ввода пользователя. Есть ли более простой способ сделать это?

+3

Этого не хватает информации о приложении. Это приложение командной строки, графическое, фоновое сетевое обслуживание или что? У него уже есть основной цикл событий? Использует ли он некоторые рамки для этого? –

+0

Программа использует интерфейс ncurses. И да, в нем есть основной цикл событий. – Tomas

ответ

2

Один из способов сделать это использовать alarm(2) системный вызов для отправки SIGALRM к процессу, когда таймер истекает:

void sigalrm_handler(int sig) 
{ 
    // This gets called when the timer runs out. Try not to do too much here; 
    // the recommended practice is to set a flag (of type sig_atomic_t), and have 
    // code elsewhere check that flag (e.g. in the main loop of your program) 
} 

... 

signal(SIGALRM, &sigalrm_handler); // set a signal handler 
alarm(10); // set an alarm for 10 seconds from now 

Обратите особое внимание на предостережениях в человеке странице alarm:

сигнала() и setitimer() одни и те же таймер; звонки на одного будут мешать использованию другого.

sleep() может быть реализован с использованием SIGALRM; смешение звонков до alarm() и sleep() - плохая идея.

Запланированные задержки могут, как всегда, задерживать процесс за какое-то время.

+0

Отлично, это именно то, что мне нужно. Благодаря! – Tomas

3

Простой, портативный способ реализации таймера прерывания использует Boost.ASIO. В частности, boost::asio::deadline_timer class позволяет указать продолжительность времени и обработчик прерываний, который будет выполняться асинхронно, когда таймер закончится.

См. here для быстрого обучения и демонстрации.

-1

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

(1) Терминология

Давайте начнем быть несколько ясно терминологии, а затем попытаться быть более ясным давая некоторые гипотетические примеры:

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

Таким образом, по аналогии, наша задача подобно TO DO список:


событие = видеоконференция с CA

времени = 9:15 утра

действие = начало видео программное обеспечение


событие = принять душ

время = 7:00 утра

действие = бодрствование SO


событие = просыпаются

времени = 6:45 утра

действие = играть Anvil Chorus


(2) Первый класс Solu Тион

Выберите натуральное число п, скажем, 1024.

Перейти к классическому алгоритму «кучного рода» и выделить и определить кучу в массиве х (1), х (2), .. ., x (n). Каждый компонент из этот массив может использоваться для хранения данных для некоторого события.

Пусть целое число m будет числом событий в куче сейчас. Начнем с m = 0. Мы будем всегда иметь m < = n. В случае, если после , выделив наш массив из n компонентов, мы обнаружим, что у нас есть больше событий для хранения , чем n, мы модифицируем это решение первого класса для решения второго класса ниже.

В куче компоненты должны иметь «заказ» на основе «ключа». В нашей куче, ключами являются часы на стене раз событий.

обзор, для положительного целого числа г = 1, 2, ... , м, для элемента массива х (I), пусть к (х (я)) будет значением ключа этого компонента. Затем (по возрастанию) 'кучи условия' представляет собой, я = 2, 3, ..., т, и позволяя я/2 целую часть этого фактора,

К (х (я/2)) < к (х (я))

Так куча не на самом деле «сортируется», но это умный и «неявные» способ хранения 2-полосная разветвленного дерева.

Есть две операции «кучи», более быстрый один и более медленный, используемый для установления состояния кучи. Более быстрая операция принимает кучу m компонентов и новое событие , помещает событие в компонент x (m + 1), рассматривает состояние кучи для i = m + 1 и обменивается, если необходимо, и т. Д. и , наконец, устанавливает m = m + 1. Более медленная операция имеет кучу m компонентов, для некоторые i = 1, 2, ..., m - 1, удаляет событие в компоненте x (i) и работает, чтобы поставить событие в x (i) и установить кучу m - 1 компонент. Подробные сведения см. В тексте об алгоритмах и структурах данных, например, «Искусство компьютера » «Программирование: сортировка и поиск» или просто детализируйте детали как упражнение.

Мы хотим, чтобы наша кучу быть в «восходящий» порядка по времени, то есть, так что х (1) имеют событие с самым ранним временем (как это и удобен, мы предполагаем, что наш компьютера часы имеют достаточно «разрешения» , что каждое время события может быть уникальным, так как ниже, каждый раз уникальный, облегчает удаление событий до того, как их действия имеют , если мы хотим это сделать).

Предположим, мы получаем событие:

Если время этого события раньше, чем текущее время, то мы просто вызвать действие этого события. Да, для некоторых приложений мы, возможно, захотим изменить этот шаг , если мы ожидаем некоторые случаи событий , прибывающих быстрее, чем мы можем принять действия ; Я обсуждаю этот пункт ниже.

Else мы помещаем событие в компоненте т + 1 массива и выполнять (быстрее) один из двух классических операций кучи снова установить состояние кучи.

Если теперь m = 1, то мы запрашиваем операционную систему для прерывания во время события в массиве x (1).

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

Когда мы получаем прерывание, мы берем действие события в компоненте массива х (1) и положим т = т - 1. Теперь массив компонент х (1) не имеет никакого события и «пусто ». Таким образом, мы должны исправить «пустой» компонент x (1) и, в частности, , чтобы снова установить состояние кучи. Для этот конец, если m> 0, мы используем ( медленнее) одну из двух операций кучи и затем запрашиваем услуги операционной системы для прерывания во время события теперь в массиве x (1).

Мы можем поддержать отмену события: Учитывая время (опять же, каждый раз уникален) в случае, используя тот факт, что куча действительно хранит бинарное дерево, найти события в куче, удалить он, и снова установите состояние кучи.

(3) Связанные приложения

Предположим, что мы получаем 2 миллиарда номера один в то время, и в конце хочу иметь 20 наименьшую. Или, если мы хотим, чтобы 20 был самым большим, мы используем восходящую кучу.

(4) Второй класс Решение

Если мы обнаружим, что п слишком мал, то мы рассматриваем кучи выше как «лист». Тогда для некоторого положительного целого k построим k-образное сбалансированное дерево, где у листьев есть n кучей компонентов, как указано выше, а узлы - это кучи k-компонент, которые указывают на узлы или листья в дереве дальше от корня из дерева.

Когда нам нужно больше узлов или листьев в дереве , мы выделяем хранилище. Как обычно, мы можем выбрать положительное целое число p и на самом деле никогда не освобождают кучи узлов до меньшего числа , чем p, и выбираем положительное целое q и фактически никогда не освобождают хранилище листьев до менее , чем q. Таким образом, мы можем «сгладить» количество распределений хранилища или бесплатно запросы на распределение динамического хранилища .

Да, здесь мы могли бы сделать некоторые оптимизации математику начиная с затратами на распределение хранения и освобождение и некоторые предположений о «стохастического прибытия процесса» событий. В связи с известной теоремой о возобновлении в стохастической точке процессов можно предположить, что процесс прибытия представляет собой просто нестационарный пуассоновский процесс с медленно меняющейся скоростью прибытия .

(5) Деталь Получение перегружен

Это может быть, что иногда события прибывают быстрее, чем мы можем принять свои действия. Итак, в 10:02 у нас могут быть 8 022 события , которые прибыли, но для которых у нас есть не предприняли никаких действий и со всех времен событиями раньше времени 10:02 утра. Теперь что? Ну, нам еще может понравиться выполнить события в порядке возрастания на раз. Итак, мы можем пойти и поместить события в кучу и/или сбалансированное дерево , пока не «пойманы», а затем предпримите действия в порядке возрастания на времени.

(6) Проблема: Как изменить для многих ядер ?

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