Установите
Установите
Задайте значения
Предположим, что вы разрабатываете сервер, который будет обречен провести большую часть своей жизни в RECEIVE-блокированном состоянии, ожидая сообщение. Идеальным вариантом здесь было бы принять специальное сообщение, указывающее, что момент, которого мы так долго ждали, наконец настал.
Как раз при таком сценарии и надо использовать импульсы в качестве схемы уведомления. В разделе «Применение таймеров», представленном ниже, я приведу пример кода, который можно использовать для периодического получения импульсов.
Предположим, что, с другой стороны, вы выполняете некоторую работу, но не желаете, чтобы она продолжалась вечно. Например, вы ожидаете возврата из некоторой функции, но не можете точно предсказать, сколько времени на это потребуется.
В этом случае оправданным выбором является использование уведомления при помощи сигнала — возможно, даже с обработчиком. (Другой вариант, который мы обсудим позже, заключается в использовании тайм-аутов ядра; см. также параграф «_NTO_CHF_UNBLOCK» в главе «Обмен сообщениями»). В параграфе «Применение таймеров», представленном ниже, мы рассмотрим пример, использующий сигналы.
Если вы вообще не собираетесь принимать сообщения, то использование сигнала и функции
Применение таймеров
Изучив все красоты теории, давайте теперь переключим наше внимание на конкретные образцы кода, чтобы посмотреть, что можно сделать при помощи таймеров.
Чтобы работать с таймером, вам потребуется:
1. Создать объект типа «таймер».
2. Выбрать схему уведомления (сигнал, импульс или создание потока) и создать структуру уведомления (struct sigevent
).
3. Выбрать нужный тип таймера (относительный или абсолютный, и однократный или периодический).
4. Запустить таймер.
Давайте теперь рассмотрим все это по порядку.
Создание таймера
Первый этап — это создание таймера с помощью функции
#include
#include
int timer_create(clockid_t clock_id,
struct sigevent *event, timer_t *timerid);
Аргумент
• CLOCK_REALTIME
• CLOCK_SOFTTIME
• CLOCK_MONOTONIC
Сигнал, импульс или поток?
Оставим пока на время варианты CLOCK_SOFTTIME и CLOCK_MONOTONIC, поскольку они еще пока (на момент написания книги — struct sigevent
. Эта структура применяется для того, чтобы сообщить ядру о типе события, которое таймер должен сгенерировать при срабатывании. Мы уже обсуждали порядок заполнения struct sigevent
, когда говорили о выборе схемы уведомления.
Итак, мы вызываем функцию struct sigevent
, и ядро создает объект типа «таймер» (он возвращается в последнем аргументе). Этот объект представляет собой небольшое целое число, которое является номером таймера в таблице таймеров ядра. Считайте его просто «дескриптором».
На этот момент никаких событий пока не происходит. Вы просто создали таймер, но ведь вы еще не включали его.
Какой таймер выбрать?
Создав таймер, теперь вы должны решить, какого типа будет этот таймер. Это осуществляется путем комбинирования аргументов функции
#include
int timer_settime(timer_t timerid, int flags,
struct itimerspec *value, struct itimerspec *oldvalue);
Аргумент
С помощью аргумента
Если вы передаете константу TIMER_ABSTIME, получается абсолютный таймер, как вы и могли бы предположить. Затем вы передаете реальные дату и время срабатывания таймера.
Если вы передаете нуль, таймер предполагается относительным.