Книга: Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform

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

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

Создав таймер, теперь вы должны решить, какого типа будет этот таймер. Это осуществляется путем комбинирования аргументов функции 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;

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

Оглавление книги


Генерация: 0.488. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз