Тип it_value аргумента new_value определяет время до срабатывания таймера. Структура it_interval определяет, является ли таймер периодическим. Если оба поля структуры it_interval равны 0, таймер срабатывает в момент времени it_value и делает это только один раз. Если одно или оба поля it_interval содержат ненулевое значение, после срабатывания таймер будет сбрасываться и снова отсчитывать указанный интервал.
Процессу доступно по одному экземпляру каждого из этих трех таймеров. Делая повторный вызов setitimer(), мы изменяем характеристики существующего таймера, заданного в аргументе which. Если оба поля new_value.it_value в вызове setitimer() равны 0, любой имеющийся таймер отключается.
Если аргумент old_value не равен NULL, он должен указывать на структуру itimerval, которая используется для возвращения предыдущего значения таймера. Если оба поля структуры old_value.it_value равны 0, это означает, что перед этим таймер был выключен. Если оба поля структуры old_value.it_interval равны 0, предыдущий таймер был установлен для одиночного срабатывания в момент времени old_value.it_value. Предыдущие параметры таймера могут пригодиться, если мы намерены восстановить их после срабатывания нового таймера. Если нам не нужны эти значения, мы можем присвоить NULL аргументу old_value.
Таймер отсчитывает время в обратном направлении от начального значения (it_value) до 0. По истечении времени процессу отправляется соответствующий сигнал; после этого, если указан ненулевой интервал (it_interval), значение таймера возвращается к исходному (it_value), а отсчет повторяется.
В любой момент времени мы можем воспользоваться вызовом getitimer(), чтобы получить текущее состояние таймера и узнать, сколько времени осталось до следующего срабатывания.
#include
int getitimer(int
Возвращает 0 при успешном завершении или –1, если случилась ошибка
Системный вызов getitimer() возвращает текущее состояние таймера типа which в виде буфера, на который указывает аргумент curr_value. Это точно такая же информация, которая возвращается с помощью аргумента old_value вызова setitimer(); разница лишь в том, что для ее получения нам не нужно изменять параметры таймера. Вложенная структура curr_value.it_value возвращает количество времени, оставшееся до следующего срабатывания таймера. Это значение изменяется по мере обратного отсчета и сбрасывается во время срабатывания таймера, если при его установке структура it_interval не была равна 0. Вложенная структура curr_value.it_interval возвращает интервал таймера; это значение остается неизменным до следующего вызова setitimer().
Таймеры, установленные с помощью вызова setitimer() (и alarm(), который мы обсудим чуть ниже), действуют на протяжении всей работы функции exec(), но не наследуются дочерним процессом в результате вызова fork().
В стандарте SUSv4 вызовы getitimer() и setitimer() помечены устаревшими; вместо них рекомендуется использовать программный интерфейс POSIX-таймеров (см. раздел 23.6).
Применение вызовов getitimer() и setitimer() демонстрируется в листинге 23.1. Данная программа выполняет следующие шаги.
• Устанавливает обработчик сигнала SIGALRM
• Инициализирует поля со значением и интервалом для реального таймера (ITIMER_REAL), используя параметры, указанные в виде аргументов командной строки
• Входит в бесконечный цикл
При каждом срабатывании таймера вызывается обработчик сигнала SIGALRM, который устанавливает глобальный флаг gotAlarm
Запустив программу из листинга 23.1, мы увидим следующее:
$ ./real_timer 1 800000 1 0
Elapsed Value Interval
START: 0.00
Main: 0.50 1.30 1.00
Main: 1.00 0.80 1.00
Main: 1.50 0.30 1.00
ALARM: 1.80 1.00 1.00
Main: 2.00 0.80 1.00
Main: 2.50 0.30 1.00
ALARM: 2.80 1.00 1.00
Main: 3.00 0.80 1.00
Main: 3.50 0.30 1.00
ALARM: 3.80 1.00 1.00
That's all folks