Какой таймер выбрать?

We use cookies. Read the Privacy and Cookie Policy

Какой таймер выбрать?

Создав таймер, теперь вы должны решить, какого типа будет этот таймер. Это осуществляется путем комбинирования аргументов функции timer_settime(), которая обычно применяется для собственно запуска таймера:

#include <time.h>

int timer_settime(timer_t timerid, int flags,

 struct itimerspec *value, struct itimerspec *oldvalue);

Аргумент timerid — это число, которое вы получите обратно по вызову функции timer_create(). Вы можете создать множество таймеров, а затем вызывать timer_settime() для них по отдельности, когда вам это будет необходимо.

С помощью аргумента flags вы определяете тип таймера — абсолютный или относительный.

Если вы передаете константу TIMER_ABSTIME, получается абсолютный таймер, как вы и могли бы предположить. Затем вы передаете реальные дату и время срабатывания таймера.

Если вы передаете нуль, таймер предполагается относительным.

Давайте посмотрим, как определяется время. Вот ключевые фрагменты двух структур данных из <time.h>:

struct timespec {

 long tv_sec, tv_nsec;

};

struct itimerspec {

 struct timespec it_value, it_interval;

};

В структуре struct itimerspec есть два поля:

it_value однократно используемое значение it_interval перезагружаемое значение

Параметр it_value задает либо интервал времени от настоящего момента до момента срабатывания таймера (в случае относительного таймера), либо собственно время срабатывания (в случае абсолютного таймера). После срабатывания таймера значение величины it_interval задает относительное время для повторной загрузки таймера, чтобы он мог сработать снова. Заметим, что задание для it_interval нулевого значения преобразует данный таймер в однократный. Вы можете предположить, что чтобы создать «исключительно периодический» таймер, вам следует установить параметр it_interval в значение интервала перезагрузки, а параметр it_value — в нуль. К сожалению, последнее неверно — установка параметра it_value в нуль выключает таймер. Если вы хотите создать «исключительно периодический» таймер, присвойте it_value и it_interval одинаковые значения и создайте таймер как относительный. Такой таймер сработает один раз (с задержкой it_value), а затем будет циклически перезагружаться с задержкой it_interval.

Оба параметра it_value и it_interval фактически являются структурами типа struct timespec — еще одного POSIX-объекта. Эта структура позволяет вам обеспечить разрешающую способность на уровне долей секунд. Первый ее элемент, tv_sec, — это число секунд, второй элемент, tv_nsec, — число наносекунд в текущей секунде. (Это означает, что никогда не следует устанавливать параметр tv_nsec в значение, превышающее 1 миллиард — это будет подразумевать смещение на более чем 1 секунду).

Несколько примеров:

it_value.tv_sec = 5;

it_value.tv_nsec = 500000000;

it_interval.tv_sec = 0;

it_interval.tv_nsec = 0;

Это сформирует однократный таймер, который сработает через 5,5 секунды. (5,5 секунд складывается из 5 секунд и 500,000,000 наносекунд.)

Мы предполагаем здесь, что этот таймер используется как относительный, потому что если бы это было не так, то его время срабатывания уже давно бы его истекло (5.5 секунд с момента 00:00 по Гринвичу, 1 января 1970).

Другой пример:

it_value.tv_sec = 987654321;

it_value.tv_nsec = 0;

it_interval.tv_sec = 0;

it_interval.tv_nsec = 0;

Данная комбинация параметров сформирует однократный таймер, который сработает в четверг, 19 апреля 2001 года в 00:25:21 по EDT. (Существует множество функций, которые помогут вам преобразовать воспринимаемый человеком интервал времени в «число секунд, истекшее с 00:00:00 по Гринвичу, 1 января 1970 года». См. функции time(), asctime(), ctime(), mktime(), strftime(), и т.д.).

В данном примере мы предполагаем, что это абсолютный таймер, поскольку в противном случае ждать пришлось бы достаточно долго (987654321 секунд — приблизительно 31.3 года).

Отметьте, что в двух приведенных выше примерах я говорил: «мы предполагаем». В коде функции timer_settime() нет никаких проверок на правильность аргументов! Вы должны самостоятельно доопределить, является таймер абсолютным или относительным. Что до ядра, то оно будет просто счастливо запланировать какое-нибудь событие на 31.3 года вперед.

И еще один пример:

it_value.tv_sec = 1;

it_value.tv_nsec = 0;

it_interval.tv_sec = 0;

it_interval.tv_nsec = 500000000;

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