线程中的信号处理比进程中信号处理更复杂。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;
}