信号的产生于处理
程序员文章站
2022-03-19 14:52:56
...
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)//显示pending表的位图
{
int i = 1;
for( ;i<=31; i++)
{
if(sigismember(pending, i))//
printf("1");//1表示信号产生,并处于未决状态
else
printf("0");//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);//屏蔽2号信号
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);//10秒后解除对2号信号的屏蔽
}
}
return 0;
}
结果预测:在代码前台运行后先是打印31个0:
原因:在代码运行时没有信号产生,也就没有信号处于未决
在ctrl+c 后第二个0变为1:
原因:ctrl+c产生2号信号发送给前台进程,又因为2号信号被阻塞,所以2号信号未决
在10秒后,又变回全0:
原因:11秒后解除对2好信号的阻塞,此时2号信号可递达在进程从内核态返回用户态之时。