23.6.1. Создание таймера: вызов timer_create()
Функция timer_create() создает новый таймер, который отсчитывает время с помощью часов, указанных в аргументе clockid.
#define _POSIX_C_SOURCE 199309
#include
#include
int timer_create(clockid_t
Возвращает 0 при успешном завершении или –1, если случилась ошибка
Аргумент clockid может содержать любое значение, указанное в табл. 23.1 или возвращаемое вызовами clock_getcpuclockid() или pthread_getcpuclockid(). Аргумент timerid указывает на буфер с идентификатором, который позволяет обращаться к таймеру в последующих вызовах. Этот буфер имеет тип timer_t, который предусмотрен стандартом SUSv3 для представления идентификаторов таймера.
Аргумент evp определяет то, каким образом программа будет уведомлена о срабатывании таймера. Он указывает на структуру типа sigevent, которая имеет следующий вид:
union sigval {
int sival_int; /* Целочисленное значение для вспомогательных данных */
void *sival_ptr; /* Указатель на вспомогательные данные */
};
struct sigevent {
int sigev_notify; /* Тип уведомления */
int sigev_signo; /* Сигнал о срабатывании таймера */
union sigval sigev_value; /* Значение, сопровождающее сигнал
или передаваемое в функцию потока */
union {
pid_t _tid; /* Идентификатор потока, который получит сигнал /
struct {
void (*_function) (union sigval);
/* Функция уведомления потока */
void *_attribute; /* Имеет тип 'pthread_attr_t *' */
} _sigev_thread;
} _sigev_un;
};
#define sigev_notify_function _sigev_un._sigev_thread._function
#define sigev_notify_attributes _sigev_un._sigev_thread._attribute
#define sigev_notify_thread_id _sigev_un._tid
Поле sigev_notify этой структуры может принимать одно из значений, перечисленных в табл. 23.2.
Таблица 23.2. Значения поля sigev_notify структуры sigevent
Значение sigev_notify — Тип уведомления — SUSv3
SIGEV_NONE — Без уведомления; отслеживание таймера с помощью timer_gettime() — *
SIGEV_SIGNAL — Отправляет процессу сигнал sigev_signo — *
SIGEV_THREAD — Начинает выполнение нового потока с функции sigev_notify_function — *
SIGEV_THREAD_ID — Отправляет сигнал sigev_signo потоку sigev_notify_thread_id
Ниже подробно описываются константы sigev_notify и поля структуры sigval, связанные с каждой из них.
• SIGEV_NONE — не отправляет уведомление о срабатывании таймера. Процесс по-прежнему может отслеживать состояние таймера с помощью вызова timer_gettime().
• SIGEV_SIGNAL — при срабатывании таймера шлет процессу сигнал, указанный в поле sigev_signo. Если это сигнал реального времени, сопутствующие данные, которые передаются вместе с ним (см. подраздел 22.8.1), должны быть указаны в поле sigev_value (это может быть целое число или указатель). Эти данные можно получить из поля si_value структуры siginfo_t, которая передается обработчику сигнала или возвращается вызовами sigwaitinfo() и sigtimedwait().
• SIGEV_THREAD — при срабатывании таймера вызывает функцию, указанную в поле sigev_notify_function. Эта функция запускается так,
• SIGEV_THREAD_ID — похоже на SIGEV_SIGNAL, но сигнал отправляется потоку, чей идентификатор равен sigev_notify_thread_id. Этот поток должен находиться в одном процессе с вызывающим потоком (в случае с SIGEV_SIGNAL сигнал попадает в очередь процесса, и если этот процесс состоит из нескольких потоков, сигнал доставляется одному из них в произвольном порядке). Поле sigev_notify_thread_id может содержать значение, возвращаемое вызовами clone() или gettid(). Флаг SIGEV_THREAD_ID предназначен для использования в потоковых библиотеках (он требует, чтобы при реализации многопоточности был задействован параметр CLONE_THREAD, описанный в подразделе 28.2.1; этому требованию удовлетворяет современная потоковая библиотека NPTL, в отличие от более старой реализации под названием LinuxThreads).
Все вышеперечисленные константы, кроме SIGEV_THREAD_ID (которая доступна только в Linux), входят в стандарт SUSv3.
Аргументу evp можно присвоить значение NULL, тогда результат будет таким же, как если бы мы указали для полей sigev_notify, sigev_signo и sigev_value.sival_int значения SIGEV_SIGNAL, SIGALRM (может варьироваться в зависимости от системы, так как в стандарте SUSv3 сказано лишь «номер сигнала по умолчанию») и соответственно идентификатор таймера.