В своей программе я использовал несколько таймеров для реализации протокола выборочного повтора. Я создаю 10 потоков за раз, и каждый из них создает новый таймер.
void void *timer(void *args) {
int seqnum = *((int *)args);
struct sigevent sevp;
struct itimerspec its;
/* inizializzo le strutture necessarie ad impostare l'allarma */
memset(&sevp, 0, sizeof(sevp));
sevp.sigev_notify = SIGEV_THREAD_ID;
sevp.sigev_signo = SIGALRM;
sevp._sigev_un._tid = gettid();
/* creo il timer */
if(timer_create(CLOCK_REALTIME, &sevp, &timerid[seqnum]) == -1) {
perror("timer_create");
exit(1);
}
/* inizializzo le strutture per armare l'allarme */
its.it_interval.tv_sec = timeout_interval.tv_sec;
its.it_interval.tv_nsec = timeout_interval.tv_nsec;
its.it_value.tv_sec = timeout_interval.tv_sec;
its.it_value.tv_nsec = timeout_interval.tv_nsec;
/* armo l'allarme */
if(timer_settime(timerid[seqnum], 0, &its, NULL) == -1) {
perror("timer_settime");
exit(1);
}
/* finchè non arrivà l'ack per il nostro pacchetto */
while(ack[seqnum] == 0) {
pause();
}
/* disarmo l'allarme e lo cancello */
if(timer_delete(timerid[seqnum]) == -1) {
perror("timer_delete");
exit(1);
}
pthread_detach(pthread_self());
printf("Thread %ld terminate\n", pthread_self());
pthread_exit((void *) 0);
}
Я настраиваю SIGALRM в основном потоке с помощью sigaction. Переменная timerid [] объявляется глобально. Функция timer_create никогда не выходит из строя, и я уверен, что содержимое структуры itimerspe c верное. Итак, что же вызывает сбой timer_settime? Программа также работает 10000 циклов без ошибок, порождая каждый раз 10 потоков, но через некоторое время возникает ошибка. Я не могу найти в Интернете ничего подобного этой проблеме. Где я не прав? Иногда также timer_delete вызывает ошибку очень странным образом: она появляется после завершения потока, как это возможно?