signal handling in thread

线程中的信号处理比进程中信号处理更复杂。APUE中建议使用一个单独的进程来同步的处理(等待)信号的到来,而其他的线程则block所有的信号。

 

下面这是一个简单的例子。

需要注意的是:

使用sigwait前,需要先block想要等待的信号,否则会产生窗口,而丢失信号。

书上是这么说的,我觉得block信号是要在sigwait用在循环里时才需要的。

这点应该和sigsuspend是一样的。

 

#include <apue.h>
#include <pthread.h>

int         quitflag = 0;
sigset_t    mask;

pthread_mutex_t  lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t   wait = PTHREAD_COND_INITIALIZER;

void*
thr_fn(void *arg)
{
    int err, signo;

    for (;;)
    {
        err = sigwait(&mask, &signo);
        if (err != 0)
            err_exit(err, "sigwait failed");
        switch (signo)
        {
            case SIGINT:
                printf("/ninterrupt/n");
                break;

            case SIGQUIT:
                pthread_mutex_lock(&lock);
                quitflag = 1;
                pthread_mutex_unlock(&lock);
                pthread_cond_signal(&wait);
                return(0);

            default:
                printf("unexpected signal %d/n", signo);
                exit(1);
        }
    }
}

int
main ()
{
    int       err;
    sigset_t  oldmask;
    pthread_t tid;

    sigemptyset(&mask);
    sigaddset(&mask, SIGINT);
    sigaddset(&mask, SIGQUIT);
    if ((err = pthread_sigmask(SIG_BLOCK, &mask, &oldmask)) != 0)
        err_exit(err, "SIG_BLOCK error");

    err = pthread_create(&tid, NULL, thr_fn, 0);
    if (err != 0)
        err_exit(err, "can't create thread");
   
    pthread_mutex_lock(&lock);
    while (quitflag == 0)
        pthread_cond_wait(&wait, &lock);
    pthread_mutex_unlock(&lock);

    /* SIGQUIT has been caught and is now blocked; do whatever */
    quitflag = 0;

    /* reset signal mask which unblocks SIGQUIT */
    if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
        err_sys("SIG_SETMASK error");

    exit(0);
    return 0;
}

你可能感兴趣的:(thread,null,Signal)