多个定时器将信号传递给单独的线程

时间:2016-04-17 10:35:10

标签: c multithreading timer

我正在开发一个应用程序,其中我使用timer_create函数创建了一个计时器,该函数在到期时向线程发送信号。到目前为止,我能够实现向特定线程传递定时器信号。我现在面临的问题是,如果有另一个计时器,如何将信号传递到另一个单独的线程(基本上第一个定时器信号到线程A,第二个定时器信号到线程B)。这是我到目前为止所写的内容

static void *
sig_threadproc(void *thrarg)
{
    sigset_t sigset;
    sigemptyset(&sigset);
    sigaddset(&sigset, SIGALRM);

/* endless loop to wait for and handle a signal repeatedly */
for (;;) {
    int sig;
    int error;

    error = sigwait(&sigset, &sig);
    if (error == 0) {
        assert(sig == SIGALRM);
        printf("got SIGALRM\n");
    } else {
        perror("sigwait");
    }
}
return NULL;
}

static void
sig_alrm_handler(int signo)
{
    /**
     * dummy signal handler, 
     * the signal is actually handled in sig_threadproc() 
     **/
}


int
main(int argc, char *argv[])
{
    sigset_t sigset;
    struct sigaction sa;
    pthread_t sig_thread;
    struct itimerspec tspec;
    timer_t timer_id;

/* mask SIGALRM in all threads by default */
sigemptyset(&sigset);
sigaddset(&sigset, SIGALRM);           
sigprocmask(SIG_BLOCK, &sigset, NULL);

/* we need a signal handler.
 * The default is to call abort() and 
 * setting SIG_IGN might cause the signal
 * to not be delivered at all.
 **/
memset(&sa, 0, sizeof(sa));
sa.sa_handler = sig_alrm_handler;
sigaction(SIGALRM, &sa, NULL);

/* create SIGALRM looper thread */
pthread_create(&sig_thread, NULL, sig_threadproc, NULL);

/* setup timer */
tspec.it_interval.tv_sec = 1;
tspec.it_interval.tv_nsec = 0;
tspec.it_value.tv_sec = 1;
tspec.it_value.tv_nsec = 0;

timer_create(CLOCK_REALTIME, NULL, &timer_id);
timer_settime(timer_id, 0, &tspec, NULL);

/**
 * this might return early if usleep() is interrupted (by a signal)
 * It should not happen, since SIGALRM is blocked on the
 * main thread
 **/
usleep(10000000);

return 0;
    }

1 个答案:

答案 0 :(得分:0)

不要将SIGALRM用于实时计时器,而是使用SIGRTMIN。因此,您将创建两个计时器,对于第一个计时器,将sigev_signo参数的sevp成员设置为SIGRTMIN + 0,并将第二个segev_signo设置为SIGRTMIN + 1 {1}}。这意味着当第一个计时器触发时,您的进程将收到SIGRTMIN信号,当第二个计时器触发时,您将收到SIGRTMIN + 1

然后在程序的2个线程中调用pthread_sigmask,在线程B中屏蔽信号SIGRTMIN,并在线程A中屏蔽SIGRTMIN + 1

结果,您的线程A将仅在第一个计时器触发时通知,而线程B将从第二个计时器获得通知。