引言
① sigprocmask的行为在多线程的进程中没有定义,线程必须使用pthread_sigmask。
② 每个线程都有自己的信号屏蔽字,这意味着单个线程可以组织某些信号!使用pthread_sigmask可以达到该目的。
int pthread_kill
(pthread_t tid, int signo); // 向线程tid发送signo信号
返回值:成功,返回0;失败,返回错误编号。
int pthread_sigmask
(int how, const sigset_t *restrict set, sigset_t *restrict oldset); // 屏蔽 or 解除
返回值:成功,返回0;失败,返回错误编号。
线程可以通过调用 sigwait 等待
set中某个信号的出现
int sigwait(const sigset_t *restrict set, int *restrict signop);
#include "apue.h"
#include <pthread.h>
int quitflag; /* set nonzero by thread */
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); //阻塞,直到mask中的某个信号产生才返回
if(err != 0)
err_exit(err, "sigwait failed");
switch(signo) //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(void)
{
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);
}