1. 信号在产生后的三种情况:
1. 阻塞 (blok),进程可以选择阻塞(blok)某个信号,被阻塞的信号,在产生后将保持未决状态,直到阻塞被解除,才有可能抵达该信号。
2. 未决(pending)信号从产生到递达之间的状态,就是未决状态,
3. 处理 (信号的递达delivery):
信号的处理三种方式:
1. 执行该信号的默认处理方式(如2号信号默认退出程序)
2.忽略此信号(不是阻塞该信号,阻塞是信号没被处理里之前的状态)
3.自定义动作(信号的捕捉)可用函数:signal()或者sigaction()
1. 1号信号SIGHUP信号未阻塞也未产⽣生过,当它递达时执⾏行默认处理动作。 2. 2号信号SIGINT信号产⽣生过,但正在被阻塞,所以暂时不能递达(在此之间为未决状态)。虽然它的处理动作是忽略,但在没有解除阻塞之前不能忽略这个信号,因为进程仍有机会改变处理动作之后再解除阻塞。 3. 3号信号SIGQUIT信号未产⽣生过,⼀一旦产⽣生SIGQUIT信号将被阻塞,它的处理动作是⽤用户⾃自定义函数sighandler。
2.测试信号屏蔽与解除并抵达
#include<stdio.h>
#include<signal.h>
void showpending(sigset_t *pending)
{
int i =
1;
for( ;i<=
31; i++)
{
if(sigismember(pending, i))
printf(
"1");
else
printf(
"0");
}
printf(
"\n");
}
void handler(
int sig)
{
printf(
"get a sig :%d",sig);
}
int main()
{
signal(
2, handler);
sigset_t bset, obset;
sigemptyset(&bset);
sigemptyset(&obset);
sigaddset(&bset,
2);
sigprocmask(SIG_SETMASK,&bset, &obset);
sigset_t pending;
int i =
0;
while(
1){
sigpending(&pending);获取信号pending表
showpending(&pending);打印信号pending表
sleep(
1);
if(i++ ==
10)
{
printf(
"recover sig block\n");
sigprocmask(SIG_SETMASK, &obset, NULL);
}
}
return 0;
}
结果预测:在代码前台运行后先是打印31个0:
原因:在代码运行时没有信号产生,也就没有信号处于未决
在ctrl+c 后第二个0变为1:
原因:ctrl+c产生2号信号发送给前台进程,又因为2号信号被阻塞,所以2号信号未决
在10秒后,又变回全0:
原因:11秒后解除对2好信号的阻塞,此时2号信号可递达在进程从内核态返回用户态之时。