信号的产生于处理

本文介绍进程如何通过阻塞、未决及处理三种状态管理信号,包括信号的默认处理、忽略和自定义处理方式。通过一个C语言示例程序演示了信号从产生到递达的全过程,特别是信号被阻塞时的状态变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值