pthread_sigmask()函数用来改变或者设置线程的信号屏蔽(signal mask)。
newmask用来执行信号屏蔽,设置信号屏蔽之前的信号屏蔽被存放到oldmask指向的位置。改变的方式由第一个参数how决定。如果how是SIG_SETMASK则把信号屏蔽值设置为newmask;如果how是SIG_BLOCK,那么在newmask中指定的信号就添加到了当前信号的屏蔽中;如果how是SIG_UNBLOCK,那么newmask中指定的信号从当前信号屏蔽中被删除。
sigwait()挂起调用sigwait()的线程,直到收到第一个参数set指向的信号集中指定的信号,且等待到信号被存放到第二个参数sig指向的位置。这里需要注意的是,在多线程情况下,执行sigwait()的时侯,sigwait()的第一个参数指向的信号集中的信号必须被阻塞。如果sigwait()等待的信号有相应的信号处理函数将不被调用。
在linux中,使用sigset_t数据类型存放信号集合。对信号集合的操作的GNU C library提供了一些函数:
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set, int signum);
int sigdelset(sigset_t *set, int signum);
int sigismember(sigset_t *set, int signum);以上这些函数包含在signal.h中
其中:
sigemptyset把set指向的信号集清空。
sigfillset初始化信号集让其包括所有的信号。
sigaddset把信号signo添加到信号集中。
sigdelset是从信号集删除信号signo。
sigismember用来判断某个信号signo是否在信号集中。
例子:#include <iostream> #include <signal.h> #include <pthread.h> using namespace std; const int THREAD_NUMBER = 2; pthread_t pt[THREAD_NUMBER]; void sigHandler(int signo) { switch (signo) { case SIGUSR1: { cout<<"thread "<<pthread_self()<<" : in signal handler: get signal SIGUSR1"<<endl; break; } case SIGUSR2: { cout<<"thread "<<pthread_self()<<" : in signal handler: get signal SIGUSR2"<<endl; break; } default: { break; } } } void * thread1(void * arg) { sigset_t newmask,oldmask,waitset; int ret_val; int signo; sigemptyset(&waitset); sigemptyset(&newmask); //initialize the signal set,and block signal SIGUSR1 while waiting for signal SIGUSR2 sigaddset(&newmask,SIGUSR1); //initialize the signal set,and wait for SIGUSR2 sigaddset(&waitset,SIGUSR2); cout<<"thread 1 ID is :"<<pthread_self()<<endl; //block signal SIGUSR1 ret_val = pthread_sigmask(SIG_BLOCK,&newmask,&oldmask); if (ret_val) { cout<<"pthread_sigmask error"<<endl; pthread_exit(0); } else { cout<<"pthread_sigmask done"<<endl; } cout<<"pthread 1 calls sigwait"<<endl; sigwait(&waitset,&signo); if (SIGUSR2 == signo) { cout<<"in thread 1 routing: thread 1 received signal SIGUSR2"<<endl; } ret_val = pthread_sigmask(SIG_SETMASK,&oldmask,NULL); if (ret_val) { cout<<"pthread_sigmask SIG_SETMASK error!"<<endl; pthread_exit(0); } pthread_exit(0); } void * thread2(void * arg) { sleep(1); cout<<"the ID of thread 2 is:"<<pthread_self()<<endl; pthread_kill(pt[0],SIGUSR1); cout<<"thread 2 has sent SIGUSR1 to thread 1"<<endl; pthread_kill(pt[0],SIGUSR2); cout<<"thread 2 has send SIGUSR2 to thread 2"<<endl; pthread_exit(0); } int main() { int i; int retValue; signal(SIGUSR1,sigHandler); signal(SIGUSR2,sigHandler); retValue = pthread_create(&pt[0],NULL,thread1,NULL); if (retValue) { cout<<"pthread create error!"<<endl; exit(1); } else { cout<<"pthread create done!"<<endl; } retValue = pthread_create(&pt[1],NULL,thread2,NULL); if (retValue) { cout<<"pthread create error!"<<endl; exit(1); } else { cout<<"pthread create done!"<<endl; } for (i = 0; i< THREAD_NUMBER ; i++ ) { retValue = pthread_join(pt[i],NULL); if (retValue) { cout<<"pthread "<<i<<" join error!"<<endl; exit(1); } else { cout<<"pthread "<<i<<" join done!"<<endl; } } return 0; }