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

💓博主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<<"进程捕捉到了一个信号,正在自定义处理中... "<<signum<<"pid: "<<getpid()<<endl;
}
int main()
{
    signal(SIGINT,mycatch);//既可以填写定义的宏,也可以直接写数字
    while(1)
    {
       cout<<"我是一个进程,我正在运行...pid: "<<getpid()<<endl;
        sleep(1);
    }
    return 0;
}

下面的内容能掌握的最好:

在这里插入图片描述

信号集操作函数概览:

在这里插入图片描述

读取或更改信号屏蔽字:
在这里插入图片描述

下面是样例代码,有兴趣可以看看:

void showpending(sigset_t& tmp)
  {
      for(int i=1;i<=31;i++)
      {
          if(sigismember(&tmp,i))
              cout<<1;
          else
              cout<<0;
      }
      cout<<endl;
  }
  void blocksig(int sig)//对指定信号对屏蔽
  {
      sigset_t bset;
      sigemptyset(&bset);
      sigaddset(&bset,sig);
      int n = sigprocmask(SIG_BLOCK,&bset,NULL);//只对sig号信号屏蔽
      assert(n==0);
      cout<<"block success!"<<endl;
  }
  int main()
  {
      cout<<getpid()<<endl;
      for(int i=1;i<=31;i++)//将所有信号都屏蔽掉
          blocksig(i);
      sigset_t pending;    
      while(1)
      {
          sigpending(&pending);    
          showpending(pending);
          sleep(1);
      }
      return 0;
  }


5. 进程是如何捕捉信号的?

先说结论:

从内核态返回用户态时,会进行信号的检测和处理

在此之前,大家肯定会有疑问:什么是内核态?什么是用户态?为什么这两个状态会相互切换?下面就来解答这些问题:

用户态指的是程序在执行用户写的代码时,会使用用户态的身份来执行代码,那么什么时候会进入内核态呢?答案是代码中存在系统调用,代码出现异常等情况,操作系统会将身份切换为内核态来执行代码.所以为什么要切换状态呢?直接用用户态执行全部代码难道不行吗?答案一定是否认的,因为群众中有坏人,在执行系统调用时,由于是很底层的代码或函数,所以操作系统是不信任用户的,切换为内核态的一大原因是为了安全性.另一方面,使用内核态执行代码时的优先级非常高.那么操作系统是怎样在两个状态中做切换的呢?答案很简单,CPU有两套寄存器,一套是可见的,一套是不可见的,而在不可见的这一套寄存器中,有一个寄存器叫CR3,它表示当前CPU的执行权限,数值为1代表内核态,数值为3代表用户态

了解完前景知识后,我们就可以得出一些结论:

  1. 当程序执行系统调用时会进入到内核态
  2. 当执行完系统调用后,会回到用户态
  3. 在这期间会进行信号的检测和处理
  4. 如若此时检测到有信号到来,那么会把代码直接跳转到信号处理的函数处
  5. 当信号处理函数返回时还会执行特殊的系统调用,再回到内核态

下面可以用一张图来代表整个过程:

在这里插入图片描述

把图片简化一下,就得到了一个无穷大的图像:

在这里插入图片描述


6. 总结

大家下来可以去试试将所有的信号都设置为阻塞,或者忽略,会发生什么?一旦这样做,进程运行起来后使用CTRL+c或者CTRL+/都不能终止进程,并且使用kill命令也无法杀掉进程.即使如此,即使所有信号都被屏蔽或忽略,但第九号信号是无法被屏蔽和忽略的,所以任何情况下都可以使用kill -9 pid来杀掉一个进程

信号这一章节是我们学习进程的最后一节,由于信号与进程的紧密关系,所以学习信号至关重要,除此之外,当子进程退出时也会向父进程发生SIG_CHILD信号,假设父进程并不想关心子进程的退出结果,只想执行自己的代码,那么我们可以将SIGCHLD信号设置为忽略,这样一来,父进程收到子进程退出的信号后就不会再拿一部分时间或资源来处理子进程了!


🔎 下期预告:线程的基本概念 🔍

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/435901.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

设计高并发秒杀系统:保障稳定性与数据一致性

✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天开心哦&#xff01;✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; 目录 引言 一. 系统架构设计 1. 系统架构图 二、 系统流程 三…

Github 2024-03-07 开源项目日报Top10

根据Github Trendings的统计,今日(2024-03-07统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目4C++项目3C#项目1TypeScript项目1非开发语言项目1HTML项目1CSS项目1屏幕截图转代码应用 创建周期:114 天开发语言:TypeScript, Pyt…

【VTKExamples::PolyData】第五十三期 WeightedTransformFilter

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 公众号:VTK忠粉 前言 本文分享VTK样例WeightedTransformFilter,并解析接口vtkWeightedTransformFilter,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就…

二维码门楼牌管理系统应用场景:助力紧急服务

文章目录 前言一、紧急服务部门的传统挑战二、二维码门楼牌管理系统的优势三、实际应用案例分析四、未来展望 前言 随着城市化的快速发展&#xff0c;传统的门牌管理系统已无法满足现代社会的需求。二维码门楼牌管理系统的出现&#xff0c;为紧急服务部门&#xff08;如警察、…

RabbitMQ 交换器

RabbitMQ 交换器 官方例子 http://www.rabbitmq.com/getstarted.html direct 如上图所示&#xff0c;两个队列绑定到了direct交换器上&#xff0c;第一个队列绑定的 binding key 为 orange &#xff0c;第二个队列有两个绑定&#xff0c;分别是 black 和 green 。 如上图所示…

C#,入门教程(26)——数据的基本概念与使用方法

上一篇&#xff1a; C#&#xff0c;入门教程(25)——注释&#xff08;Comments&#xff09;你会吗&#xff1f;看多图演示&#xff0c;学真正注释。https://blog.csdn.net/beijinghorn/article/details/124681888 本文所述的知识基本上适用于C/C&#xff0c;java等其他语言。 …

脉宽调制PWM控制器有哪些国产替代可选择?

一、脉宽调制PWM简介 PWM的理论基础为面积等效原理&#xff0c;这个原理简单描述就是冲量相等&#xff08;信号对时间的积分&#xff0c;即面积&#xff09;而形状不同的窄脉冲加在具有惯性的环节上时&#xff0c;其效果基本相同。冲量相等而形状不同的窄脉冲加在具有惯性的环…

基于机器学习的垃圾分类

1绪论 1.1问题背景 垃圾分类有减少环境污染、节省土地资源、再生资源的利用、提高民众价值观念等的好处&#xff0c;在倡导绿色生活&#xff0c;注重环境保护的今天&#xff0c;正确的垃圾分类和处理对我们的生态环境显得尤为重要。 在国外很多国家&#xff0c;经过了几十年…

vue3+ts项目创建 使用npm create vue@latest

npm create vuelatest相关创建代码&#xff1a;

[Spring Boot] 集成Nacos

文章目录 Spring Boot 集成nacosSpring Boot版本pom配置引入bootstrap.yml 增加配置启动项目 版本对应关系2022.x 分支2021.x 分支2.2.x 分支 组件版本关系 Spring Boot 集成nacos Spring Boot版本 本文采用 2.6.13 其他版本可见文末版本对应 <parent><groupId>o…

Tomcat介绍在IDEA中创建JavaWeb工程

文章目录 一、WEB服务器服务器概述使用Java代码手写web服务器 二、服务器软件Web服务器服务器软件的使用步骤 三、TomcatTomcat的下载Tomcat的安装与卸载Tomcat的启动与关闭常见问题 四、新建Java Web项目并将项目部署到tomcat中新建Java Web项目将项目部署到Tomcat中出现的问题…

1.3 数据库系统的结构

目录 1.3.1 数据库系统模式的概念 1.3.2 数据库系统的三级模式结构 1. 模式 2. 外模式 3.内模式&#xff08;也称存储模式&#xff09; 1.3.3 数据库的二级映像功能与数据独立性 1.外模式&#xff0f;模式映像 2.模式&#xff0f;内模式映像 1.3.4 总结 模式 内模式…

Linux——线程同步互斥(线程安全)

线程互斥 进程线程间的互斥相关背景概念 临界资源&#xff1a;多线程执行流共享的资源就叫做临界资源临界区&#xff1a;每个线程内部&#xff0c;访问临界资源的代码&#xff0c;就叫做临界区互斥&#xff1a;任何时刻&#xff0c;互斥保证有且只有一个执行流进入临界区&…

K倍区间 刷题笔记

法一 前缀和暴力搜索 &#xff08;数据大会超时&#xff09; #include<iostream> #include<cstring> #include<algorithm> #include<cstdio> using namespace std; const int N100010; int a[N],s[N]; int n,k; int main(){ cin>>n>>…

第3部分 原理篇3可验证凭证(VC)(1)

3.3. 可验证凭证 3.3.1. 本节内容概述 本聪老师&#xff1a;今天开始去中心化身份中另一个最重要的概念可验证凭证&#xff08;verifiable credential&#xff09;的学习。凭证&#xff0c;也就是证件&#xff0c;在人类生活中不可或缺。可验证凭证实现了凭证的机器可读、加密…

微信小程序(五十一)页面背景(全屏)

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.页面背景的基本写法 2.去除默认上标题实习全屏背景 3. 背景适配细节 源码&#xff1a; index.wxss page{/* 背景链接 */background-image: url(https://pic3.zhimg.com/v2-a76bafdecdacebcc89b5d4f351a53e6a_…

嵌入式开发的常用软件、学习资源网站推荐

1、软件推荐 1.1、文本编辑软件 ——Notepad 1、适合编写和查看文本文件&#xff0c;也可以安装插件来查看二进制文件、对比文件 2、参考博客&#xff1a;《Notepad实用小技巧》&#xff1b; 1.2、PDF文件阅读软件——福昕PDF阅读器 福昕PDF阅读器&#xff0c;在官网就可以下载…

部署YOLOv8模型的实用常见场景

可以的话&#xff0c;GitHub上点个小心心&#xff0c;翻不了墙的xdm&#xff0c;csdn也可以点个赞&#xff0c;谢谢啦 车流量检测&#xff08;开源代码github&#xff09;&#xff1a; test3 meiqisheng/YOLOv8-DeepSORT-Object-Tracking (github.com) 车牌检测&#xff0…

Docker前后端项目部署

目录 一、搭建项目部署的局域网 二、redis安装 三、MySQL安装 四、若依后端项目搭建 4.1 使用Dockerfile自定义镜像 五、若依前端项目搭建 一、介绍前后端项目 二、搭建项目部署的局域网 搭建net-ry局域网&#xff0c;用于部署若依项目 docker network create net-ry -…

node模块分类

模块 分类 在node种有很多模块&#xff0c;有我们自己写的javascript文件&#xff0c;也会有javascript自带的&#xff0c;还有我们可以下载别人写好的javascript。主要分为三大类。 1. 内置模块 在安装node的时候就自带的模块&#xff0c;比如说http、fs、path等。内置模块一…