欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

信号的产生于处理

程序员文章站 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号信号可递达在进程从内核态返回用户态之时。

信号的产生于处理

相关标签: 信号