Единственный трюк здесь заключается в том, что всякий раз, когда поступает сообщение от клиента, использующего данные аппаратные средства, вы должны восстановить первоначальное значение этой переменной, поскольку обращение к ресурсу должно сбрасывать «обратный отсчет». И наоборот, аппаратным средствам может потребоваться определенный промежуток времени «на разогрев» после включения. В этом случае после выключения аппаратных средств вам придется при поступлении запроса от клиента организовать еще один таймер, чтобы «придержать» запрос до того момента, пока аппаратные средства не станут готовы.
Таймеры, посылающие сигналы
На настоящий момент мы уже рассмотрели практически все, что относится к таймерам, за исключением одного небольшого момента. Мы обеспечивали отправку импульса, но у нас также есть возможность посылать POSIX-сигналы. Давайте посмотрим, как это делается:
timer_create(CLOCK_REALTIME, NULL, &timerid);
Это простейший способ создать таймер, который будет посылать вам сигнал. Он обеспечивает выдачу сигнала SIGALRM при срабатывании таймера. Если бы мы предоставили struct sigevent
, мы могли бы определить, какой именно сигнал мы хотим получить:
struct sigevent event;
SIGEV_SIGNAL_INIT(&event, SIGUSR1);
timer_create(CLOCK_REALTIME, &event, &timerid);
Это обеспечит нам выдачу сигнала SIGUSR1 вместо SIGALRM.
Сигналы таймера перехватываются обычными обработчиками сигналов, здесь нет ничего необычного.
Таймеры, создающие потоки
Если вы хотите по каждому срабатыванию таймера создавать новый поток, то вы можете это сделать с помощью struct sigevent
и всех остальных таймерных штук, которые мы только что обсудили:
struct sigevent event;
SIGEV_THREAD_INIT(&event, maintenance_func, NULL);
Однако, пользоваться этим надо очень осторожно, потому что если вы определите слишком короткий интервал, вы можете просто утонуть в создаваемых потоках. Они просто поглотят все ресурсы вашего процессора и оперативной памяти.
Опрос и установка часов реального времени, и кое-что еще
Независимо от применения таймеров, вы можете также опрашивать и устанавливать часы реального времени, а также и плавно подстраивать их. Для этих целей можно использовать следующие функции:
Функция | Тип | Описание |
---|---|---|
QNX/Neutrino | Плавная регулировка времени | |
QNX/Neutrino | Опрос с высоким разрешением | |
POSIX | Выборка базового разрешения | |
POSIX | Получение текущего времени суток | |
QNX/Neutrino | Получение/установка базового разрешения | |
POSIX | Установка текущего времени суток | |
QNX/Neutrino | Получение/установка текущего времени суток |
Функции
Если нужна плавная корректировка текущего времени, ее можно реализовать с помощью функции
int ClockAdjust(clockid_t id,
const struct _clockadjust *new,
const struct _clockadjust *old);