Linux系统编程之信号(下)

3、信号的保存

在聊这个之前首先要了解一些术语

实际执行信号的处理动作称为信号递达(Delivery)
信号从产生到递达之间的状态,称为信号未决(Pending)。
进程可以选择阻塞 (Block )某个信号。
被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作.
注意,阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后可选的一种处理动作。

 其中这三个对应pcb中的一个数据结构,那就位图结构,由block位图和pending位图和handler函数指针数组,发送信号过来首先要查看block位图,看看有没有阻塞掉当前的信号,如果阻塞了就不会访问pending位图,如果没有阻塞就会将pending位图由零置为一,在找他对应的函数指针去执行函数。

3.5 sigset_t

每个信号只有一个bit的未决标志,非0即1,不记录该信号产生了多少次,阻塞标志也是这样表示的。
因此,未决和阻塞标志可以用相同的数据类型sigset_t来存储,sigset_t称为信号集,这个类型可以表示每个信号
的“有效”或“无效”状态,在阻塞信号集中“有效”和“无效”的含义是该信号是否被阻塞,而在未决信号集中“有
效”和“无效”的含义是该信号是否处于未决状态。下一节将详细介绍信号集的各种操作。

4、信号的递达

之前说过信号递达以后会在合适的时间处理,合适的时间是什么时候呢,是进程状态由内核态到用户态以后。那么如何陷入内核呢,我们需要当我们进行访问硬件资源时就会陷入内核,陷入以后在回到用户态,执行信号,在回到内核态中修改对应的位图结构,然后在出来,听起来很麻烦,其实只要将内容抽象一下,其实就是我们高中的无穷大,在这个里面关键结点我已经标出来了。记住这个图就可以很清晰的描述信号的递达过程。

在信号递达以后,有三种处理方式,默认、自定义和忽略。其中默认和自定义就比较简单了,只需要找到对应函数指针,调用函数即可,忽略就有很多讲究了。首秀按需要了解一些列的接口

 

Sigpending用于处理当前进程的pending位图结构,sigpromask用于处理bolck位图的

接下来就写一个好玩的东西

static void myhandler(int signo)
{
    std::cout<<signo<<"信号已递达\n";
}
int main()
{
    for(const auto& n : v)
    {
        signal(n,myhandler);
    }
    sigset_t block,oblock/*表示输出型参数*/,pending;
    // 1. 先尝试屏蔽信号
    // 1.1初始化
    sigemptyset(&block);
    sigemptyset(&oblock);
    sigemptyset(&pending);
    // 1.2添加要屏蔽的信号
    // sigaddset(&block,BLOCK_SIGNAL);
    for(const auto& n : v)
    {
        sigaddset(&block,n);
    }
    // 1.3开始屏蔽 
    sigprocmask(SIG_SETMASK, &block, &oblock);
    // 2.遍历打印pending信号集
    int cnt = 1;
    while (1)
    {
        /* code */
        // 2.1初始化
        sigemptyset(&pending);
        // 2.2获取他
        sigpending(&pending);
        // 2.3打印他
        show_pending(pending);
        sleep(1);
        cnt++;
        if(cnt == 10) 
        {
            std::cout<<"恢复对信号的屏蔽,不屏蔽任何信号\n";
            sigprocmask(SIG_SETMASK, &oblock, &block);
        }
    }
    return 0;
}

我们屏蔽了2、3号信号,当第十秒的时候会取消屏蔽,当我一发送信号他就会立即调用对应的函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值