【linux进程信号(二)】信号的保存,处理以及捕捉

小明 2025-04-29 20:23:14 5

💓博主CSDN主页:杭电码农-NEO💓

⏩专栏分类:Linux从入门到精通⏪

🚚代码仓库:NEO的学习日记🚚

🌹关注我🫵带你学更多操作系统知识

  🔝🔝


进程信号

  • 1. 前言
  • 2. 信号阻塞,信号递到和信号忽略
  • 3. 进程是怎样保存信号的?
  • 4. 信号集操作函数
  • 5. 进程是如何捕捉信号的?
  • 6. 总结

    1. 前言

    上一篇文章了解到信号产生的四种方式,

    但是信号产生后,然后呢?需要对信号

    进行保存,最后对信号进行处理

    如果你没有阅读过前一篇文章,或者不知道信号的默认处理方式,请先阅读这篇文章: 信号的基本概念

    本章重点:

    本篇文章着重讲解信号保存的方式以及

    周边概率,信号阻塞,信号递达.理解

    信号处理的默认方式,如何修改默认方法

    最后会讲解进程是如何捕捉信号的?


    2. 信号阻塞,信号递到和信号忽略

    在讲解进程是如何保存信号之前,要

    先了解下面几个概念:

    1. 信号递达:

    实际执行处理信号的动作叫做信号的递达

    1. 信号的未决状态:

    在信号产生到信号递达之间的状态叫做信号的未决状态

    1. 信号阻塞:

    一旦一个信号被设置了阻塞之后,那么此进程就不会收到此信号

    1. 信号忽略:

    一旦一个信号被设置为忽略,那么当这个信号来临后,进程不会对此信号做处理

    1. 阻塞和忽略的区别:

    一个信号被阻塞后,它就不会递达,而忽略是指信号递达后,执行的动作是什么都不做


    3. 进程是怎样保存信号的?

    在进程的PCB中,存在三张和信号相关的表

    更准确的讲,前两个结构是位图,最后一个是表(数组).

    1. block位图:

    这个位图代表,在这个进程中,有哪些信号是被阻塞了的?位图的第一个元素为0,代表1号信号没有被阻塞,第n个位置为1,代表n号信号被阻塞了,也就是说0/1代表某个信号是否被阻塞,这个位图又被称为信号屏蔽字

    1. pending位图:

    这个位图是进程存储信号的结构,位图中的第n个位置为0/1代表是否收到了n号信号,如若收到,会在后续进行处理,这个位图又被称为信号集

    1. handler数组:

    首先,这个数组是一个函数指针数组,里面存储的是函数的地址,数组的n号元素存储的函数地址代表收到n号信号之后,要去处理信号时,需要调用的函数.在上图中,SIG_DFL宏代表这个函数就是此信号的默认处理函数,SIG_IGN宏代表收到这个信号后,直接忽略此信号,当然我们也可以自己写一个函数来充当信号的处理方法,这个后面会讲


    4. 信号集操作函数

    首先我想隆重介绍的是signal函数:

    第一个参数代表要设置几号信号

    第二个参数代表,信号到来需要调用哪个函数

    下面可以进行一个简单的编码验证:

    void mycatch(int signum)
    {
        cout
        signal(SIGINT,mycatch);//既可以填写定义的宏,也可以直接写数字
        while(1)
        {
           cout
          for(int i=1;i
              if(sigismember(&tmp,i))
                  cout
          sigset_t bset;
          sigemptyset(&bset);
          sigaddset(&bset,sig);
          int n = sigprocmask(SIG_BLOCK,&bset,NULL);//只对sig号信号屏蔽
          assert(n==0);
          cout
          cout
              sigpending(&pending);    
              showpending(pending);
              sleep(1);
          }
          return 0;
      }
    
The End
微信