Текущая реализация ядра заранее выделяет по одной структуре с сигналом реального времени для каждого POSIX-таймера, созданного с помощью вызова timer_create(). Это делается для того, чтобы гарантировать, что в момент срабатывания таймера для сохранения сигнала будет доступна как минимум одна такая структура. Это означает, что максимальное количество POSIX-таймеров, которые мы можем создать, не превышает количество сигналов реального времени, которые можно поместить в очередь (см. раздел 22.8).
23.6.2. Запуск и остановка таймера: вызов timer_settime()
Создав таймер, мы можем его запускать и останавливать, используя вызов timer_settime().
#define _POSIX_C_SOURCE 199309
#include
int timer_settime(timer_t
itimerspec *
Возвращает 0 при успешном завершении или –1, если случилась ошибка
Аргумент timerid принимает идентификатор таймера, полученный ранее из вызова timer_create().
Аргументы value и old_value аналогичны тем, что используются в вызове setitimer(): первый определяет новые параметры таймера, а второй применяется для возвращения предыдущих параметров (см. ниже описание вызова timer_gettime()). Если нас не интересуют параметры, установленные ранее, мы можем присвоить аргументу old_value значение NULL. Аргументы value и old_value являются указателями на структуры типа itimerspec, которые имеют следующий вид:
struct itimerspec {
struct timespec it_interval; /* Интервал периодического таймера */
struct timespec it_value; /* Первое срабатывание */
};
Оба поля вышеприведенной структуры, в свою очередь, являются структурами типа timespec, которая представляет время в виде секунд и наносекунд:
struct timespec {
time_t tv_sec; /* Секунды */
long tv_nsec; /* Наносекунды */
};
Поле it_value определяет момент первого срабатывания таймера. Если хотя бы одно из вложенных полей it_interval не равно 0, таймер является периодическим и после истечения времени it_value будет срабатывать с частотой, заданной с помощью этих полей. Если оба вложенных поля it_interval равны 0, таймер сработает только один раз.
Если аргумент flags равен 0, поле value.it_value интерпретируется относительно значения часов на момент вызова timer_settime() (по аналогии с setitimer()). Если аргумент flags равен TIMER_ABSTIME, поле value.it_value интерпретируется как абсолютное время (то есть отсчитывается с начальной позиции часов). Если согласно часам это время уже прошло, таймер срабатывает немедленно.
Чтобы запустить таймер, нужно сделать вызов timer_settime(), передав хотя бы одному вложенному полю value.it_value ненулевое значение. Если таймер уже был запущен ранее, вызов timer_settime() обновит предыдущие параметры.
Если значение таймера и интервал не являются кратными минимальному отрезку времени в соответствующих часах (который можно получить с помощью clock_getres()), эти значения будут округлены в большую сторону до следующего кратного.
При каждом срабатывании таймера процесс уведомляется с помощью метода, который изначально был указан в вызове timer_create(). Если внутри it_interval содержатся ненулевые значения, они используются для повторной инициализации структуры it_value.
Чтобы остановить таймер, нужно опять сделать вызов timer_settime(), присвоив 0 обоим полям структуры value.it_value.
23.6.3. Получение текущего значения таймера: вызов timer_gettime()
Системный вызов timer_gettime() возвращает интервал и время, оставшееся до срабатывания POSIX-таймера с идентификатором timerid.
#define _POSIX_C_SOURCE 199309
#include
int timer_gettime(timer_t
Возвращает 0 при успешном завершении или –1, если случилась ошибка
Интервал и время, оставшееся до следующего срабатывания таймера, возвращаются внутри структуры itimerspec, на которую указывает аргумент curr_value. Поле curr_value.it_value содержит оставшееся время, даже если таймер был сделан абсолютным с помощью значения TIMER_ABSTIME. Если оба поля возвращенной структуры curr_value.it_value равны 0, таймер не запущен. Если оба поля структуры curr_value.it_interval равны 0, таймер должен сработать только один раз в момент времени curr_value.it_value.
23.6.4. Удаление таймера: вызов timer_delete()
Любой POSIX-таймер потребляет какое-то количество ресурсов. То есть, закончив работать с таймером, его нужно удалить и освободить эти ресурсы, используя вызов timer_delete().
#define _POSIX_C_SOURCE 199309
#include
int timer_delete(timer_t
Возвращает 0 при успешном завершении или –1, если случилась ошибка