• Воспользоваться полем si_overrun из структуры siginfo_t, принятой вместе с сигналом. Такой подход является более экономным по сравнению с вызовом timer_getoverrun(), но это нестандартное решение, доступное только в Linux.
Счетчик дополнительных срабатываний сбрасывается при каждой доставке сигнала. Если с момента обработки или приема сигнала таймер сработает лишь раз, счетчик будет равен 0 (что говорит об отсутствии дополнительных срабатываний).
#define _POSIX_C_SOURCE 199309
#include
int timer_getoverrun(timer_t
Возвращает количество дополнительных срабатываний при успешном завершении или –1, если произошла ошибка
Функция timer_getoverrun() возвращает количество дополнительных срабатываний таймера, указанного в аргументе timerid. Согласно стандарту SUSv3 она является безопасной для работы с асинхронными сигналами (см. табл. 21.1), поэтому ее можно вызывать внутри обработчика.
23.6.7. Уведомление с помощью потока
Флаг SIGEV_THREAD позволяет программе получать уведомления о срабатывании таймера путем вызова функции в отдельном потоке. Для понимания этого флага нужно иметь представление о POSIX-потоках, с которыми вы познакомитесь позже, в главах 29 и 30. Возможно, вам придется прочитать эти главы, прежде чем переходить к демонстрационной программе, представленной в данном разделе.
Применение флага SIGEV_THREAD показано в листинге 23.7. Эта программа принимает те же аргументы командной строки, что и пример из листинга 23.5, и выполняет следующие шаги.
• Создает
• При каждом срабатывании таймера в отдельном потоке вызывается функция, указанная в поле sev.sigev_notify_function
• Создав и запустив все таймеры, программа входит в цикл и ждет, когда они сработают
• При каждом срабатывании таймера вызывается функция threadFunc()
Программа из листинга 23.7 демонстрируется в следующей сессии командной строки. В этом примере создается два таймера, у которых совпадают начальное время срабатывания и интервал: у одного это 5 секунд, а у второго — 10.
$ ./ptmr_sigev_thread 5:5 10:10
Timer ID: 134525024 (5:5)
Timer ID: 134525080 (10:10)
[13:06:22] Thread notify
timer ID=134525024
timer_getoverrun()=0
main(): count = 1
[13:06:27] Thread notify
timer ID=134525080
timer_getoverrun()=0
main(): count = 2
[13:06:27] Thread notify
timer ID=134525024
timer_getoverrun()=0
main(): count = 3
[1]+ Stopped./ptmr_sigev_thread 5:5 10:10
$ fg
./ptmr_sigev_thread 5:5 10:10
[13:06:45] Thread notify
timer ID=134525024
timer_getoverrun()=2
main(): count = 6
[13:06:45] Thread notify
timer ID=134525080
timer_getoverrun()=0
main(): count = 7
Листинг 23.7. Уведомления POSIX-таймеров на основе функции в отдельном потоке
timers/ptmr_sigev_thread.c
#include
#include
#include
#include "curr_time.h" /* Объявление currTime() */
#include "tlpi_hdr.h"
#include "itimerspec_from_str.h" /* Объявляет itimerspecFromStr() */
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
static int expireCnt = 0; /* Количество срабатываний всех таймеров */
static void /* Функция уведомления в отдельном потоке */
{
timer_t *tidptr;
int s;
tidptr = sv.sival_ptr;
printf("[%s] Thread notify\n", currTime("%T"));
printf(" timer ID=%ld\n", (long) *tidptr);
printf(" timer_getoverrun()=%d\n", timer_getoverrun(*tidptr));
/* Инкрементируем счетчик, разделяемый с главным потоком, и оповещаем