Указывает, какой поток настроить обработчик таймера? - PullRequest
0 голосов
/ 18 февраля 2012

Возвращаясь к этому вопросу:

У меня запущено несколько потоков (pthreads api), каждый со своим таймером, который вызывает определенный обработчик функции (int signum) после определенного интервала.Как эти потоки вызывают обработчик и внутри обработчика функции, как я узнаю, какой поток вызвал его?Требуются ли специфичные для потока данные?

Я заметил, что поток, который входит в функцию-обработчик, отличается от потока, который его настраивал, поэтому вызов pthread_self () не работает.Как мне обойти это?

Вот небольшой пример, иллюстрирующий проблему

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>

void handler(int);
void call_alarm();
void *setup(void*);

pthread_t p;

void handler(int signum)
{
    printf("handler thread %lu\n", pthread_self());
}

void call_alarm()
{   
    static struct itimerval timer;
    static struct sigaction sa;

    printf("call_alarm %lu\n", (unsigned long)pthread_self());

    sa.sa_handler = handler;
    sa.sa_flags = SA_RESETHAND;
    timer.it_value.tv_usec = 500;
    timer.it_value.tv_sec = 0;
    timer.it_interval.tv_sec = 0;
    timer.it_interval.tv_usec = 0;

    sigaction(SIGALRM, &sa, 0);
    setitimer(ITIMER_REAL, &timer, 0);
}

void *setup(void *param)
{
    while(1)
    {
        printf("caller thread %lu\n", pthread_self());
        call_alarm();
        pause();
    }
}

int main(void)
{
    if(pthread_create(&p, NULL, setup, NULL));
    while(1);
    return 0;
}

Вывод:

caller thread 3086637968
call_alarm 3086637968
handler thread 3086640832

Как вы можете видеть, это печатаетразные значения.

Ответы [ 2 ]

1 голос
/ 18 февраля 2012

Вы можете напечатать идентификатор потока, когда вызывается обработчик:

и, если вы не можете, напишите обертку функции вокруг обработчика и скажите своему коду вызывать функцию обертки вместовызов обработчика напрямую.

0 голосов
/ 18 февраля 2012

Глава POSIX о генерации и доставке сигнала гласит:

Во время генерации должно быть определено, был ли сигнал сгенерирован для процесса или дляконкретный поток в процессе.Сигналы, которые генерируются каким-либо действием, относящимся к конкретному потоку, таким как аппаратный сбой, должны генерироваться для потока, который вызвал генерирование сигнала.Сигналы, которые генерируются в связи с идентификатором процесса или идентификатором группы процессов или асинхронным событием, таким как активность терминала, должны генерироваться для процесса.

Интересно, сигнал SIGALRM сигнализирует вам?перехват не считается действием , относящимся к определенному потоку, таким как аппаратная ошибка .Похоже, ваш SIGALRM сигнал попадает во вторую категорию и генерируется для процесса.

...