每个线程都有自己的信号屏蔽字,但信号在进程中,是对所有线程共享的.
问题:
若单个线程修改了信号的处理方式,所有线程都会使用这个被修改的信号处理方式.
每个线程均有自己的信号屏蔽集(信号掩码),可以使用pthread_sigmask函数来
屏蔽某个线程对某些信号的响应处理.
解决:
每个线程都有自己的屏蔽字, 调用pthread_sigmask 来屏蔽信号处理.
kill : 用在进程间,进程中的所有线程都会接收处理,处理有线程屏蔽字.
pthread_kill :用在线程间.
子线程会继承主线程信号, 可以通过pthread_sigmask来屏蔽.
**关键接口:**
pthread_sigmask(int how, const sigset_t *restrict set, sigset_t *restrict oset);
屏蔽指定信号,配合接口sigaddset
屏蔽所有信号,....sigfillset(&mask);
不屏蔽任何信号,..sigemptyset(&mask);
(这里的屏蔽本人理解就是阻塞)
sigdelset(&set, SIGALRM);
将参数signum代表的信号从参数set信号集里删除。
sigwait(&set, &sig);
只是从未决队列中删除该信号,并不改变信号掩码。也就是,当sigwait函数返回,它监听的信号依旧被阻塞。
参考:
http://www.leoox.com/?p=321
http://blog.csdn.net/yusiguyuan/article/details/14230719
#include<stdio.h>
#include<pthread.h>
#include<signal.h>
static void sig_alrm(int signo);
static void sig_init(int signo);
int main()
{
sigset_t set;
int sig;
sigemptyset(&set);
sigaddset(&set, SIGALRM);
pthread_sigmask(SIG_SETMASK, &set, NULL);//阻塞SIGALRM信号
signal(SIGALRM, sig_alrm);
signal(SIGINT, sig_init);
sigwait(&set, &sig);//sigwait只是从未决队列中删除该信号,并不改变信号掩码。也就是,当sigwait函数返回,它监听的信号依旧被阻塞。
switch(sig)
{
case 14:
printf("sigwait, receive signal SIGALRM\n"); /*do the job when catch the sigwait*/
break;
default:
break;
}
sigdelset(&set, SIGALRM); //删除信号集中的屏蔽字. 这样pthread_sigmask接口就不会屏蔽了,就可以调用信号处理.
pthread_sigmask(SIG_SETMASK, &set, NULL);
for(;;){ }
return 0;
}
static void sig_alrm(int signo)
{
printf("after sigwait, catch SIGALRM\n");
fflush(stdout);
return ;
}
static void sig_init(int signo)
{
printf("catch SIGINT\n");
return ;
}
执行:
第一次发送kill -14 17457(进程号)时打印switch里面的语句:
sigwait, receive signal SIGALRM
之后发送SIGALRM信号的话将被信号处理程序捕捉。
after sigwait, catch SIGALRM
after sigwait, catch SIGALRM
after sigwait, catch SIGALRM