Тип 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 which, struct itimerval *curr_value);

Возвращает 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), используя параметры, указанные в виде аргументов командной строки . Если эти аргументы отсутствуют, программа устанавливает таймер, который срабатывает лишь единожды, после 2 секунд.

• Входит в бесконечный цикл , потребляя процессорное время и периодически вызывая функцию displayTimes() , которая выводит реальное время, прошедшее с момента запуска программы, а также текущее состояние таймера ITIMER_REAL.

При каждом срабатывании таймера вызывается обработчик сигнала SIGALRM, который устанавливает глобальный флаг gotAlarm . Каждый раз, когда этот флаг устанавливается, цикл в главной программе вызывает функцию displayTimes(), чтобы вывести время вызова обработчика и текущее состояние таймера (обработчик спроектирован таким образом, чтобы избежать вызова функций, несовместимых с асинхронными сигналами; причины описаны в подразделе 21.1.2). Если таймер имеет нулевой интервал, при получении сигнала программа завершается; в противном случае для ее завершения должно быть перехвачено три сигнала .

Запустив программу из листинга 23.1, мы увидим следующее:

$ ./real_timer 1 800000 1 0 Начальное значение равно 1,8 секунды,

интервал равен 1 секунде

Elapsed Value Interval

START: 0.00

Main: 0.50 1.30 1.00 Таймер ведет обратный отсчет, пока не достигнет 0

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

Перейти на страницу:

Похожие книги