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

news2025/1/19 19:26:37

💓博主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信号设置为忽略,这样一来,父进程收到子进程退出的信号后就不会再拿一部分时间或资源来处理子进程了!


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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

仅通过头部便可控制机器人实现生活自理!四肢瘫患者福音真的来了?

运动功能障碍对个体执行基本日常生活活动&#xff08;如沐浴、更衣、用餐&#xff09;以及进行工具性日常生活活动&#xff08;包括娱乐和社交互动&#xff09;造成了显著影响&#xff0c;不仅限制了他们的活动范围&#xff0c;而且削弱了他们维持独立生活的基础。受此类障碍困…

Netty架构

Netty逻辑架构 Netty 的逻辑处理架构为典型网络分层架构设计&#xff0c;网络通信层、事件调度层、服务编排层。 一、 网络通信层 网络通信层的职责是执行网络 I/O 的操作。它支持多种网络协议和 I/O 模型的连接操作。当网络数据读取到内核缓冲区后&#xff0c;会触发网络事件…

还在用Jenkins?试试这款阿里出品的IDEA插件,部署项目贼香

CloudToolkit简介 CloudToolkit是阿里出品的一款IDEA插件,通过它我们可以更方便地实现自动化部署,其内置的终端工具和文件上传功能,即使用来管理服务器也非常方便!这款IDEA插件不仅功能强大,而且完全免费! 安装 CloudToolkit的安装是非常简单的,直接在IDEA的插件市场…

如何在Vue中实现拖拽功能?

Vue.js是一款流行的JavaScript框架&#xff0c;用于构建用户界面。其中一个常见的需求是在Vue中实现拖拽功能&#xff0c;让用户可以通过拖拽元素来进行交互。今天&#xff0c;我们就来学习如何在Vue中实现这一功能。 首先&#xff0c;我们需要明白拖拽功能的基本原理&#xf…

yduibuilder,拖拽式开发轻松高效自动生成前端代码

给大家分享一个#开源项目# &#xff1a;#yduibuilder# &#xff0c;他可以通过拖拽式的开发方式自动生成前端代码&#xff0c;这种#低代码开发工具# 已经很多了&#xff0c;没什么新鲜的&#xff1b; 但yduibuilder式通过编译的方式#生成终端代码# &#xff0c;没有预设各种功能…

2.2 评估方法 机器学习

我们若有一个包含m个样例的数据集&#xff0c;若我们既需要训练&#xff0c;也需要测试&#xff0c;我们该如何处理呢&#xff1f;下面是几种方法&#xff1a; 2.2.1 留出法 “留出法”直接将数据集D划分为两个互斥的集合&#xff0c;其中一个作为训练集S&#xff0c;另一个作…

[数据结构初阶】栈

各位读者老爷好&#xff0c;鼠鼠我好久没写博客了&#xff08;太摆烂了&#xff09;&#xff0c;今天就基于C语言浅介绍一下数据结构里面的栈&#xff0c;希望对你有所帮助吧。 目录 1.栈的概念及结构 2.栈的实现 2.1定义栈 2.2.初始化栈 2.3.入栈 2.4.出栈 2.5.获取栈…

小白跟做江科大51单片机之LCD1602滚动显示效果

1.查看原理图 图1 LCD1602接口 图2 LCD1602与STC的接口 2.编写代码 图3 时序结构 根据时序结构编写命令和写入数据代码 #include <REGX52.H> #include "Delay.h" sbit LCD1602_ENP2^7; sbit LCD1602_RSP2^6; sbit LCD1602_WRP2^5; #define LCD1602_lCD0 …

Dgraph 入门教程二《 快速开始》

1、Clound 云 云地址&#xff1a;Dgraph Cloud 登录Clound 云后&#xff0c;可以用云上的东西操作&#xff0c;可以用谷歌账号或者github账号登录。 启动云 &#xff08;1&#xff09;在云控制台&#xff0c;点击 Launch new backend. &#xff08;2&#xff09;选择计划&…

AIGC工具( 7个 )

人工智能技术有好的一方面&#xff0c;又不好的地方&#xff0c;要区别对待&#xff0c;吸取精华&#xff0c;去其糟粕。目前市场上有很多AI大模型&#xff0c;可以支持聊天&#xff0c;写文稿&#xff0c;创作等&#xff0c;部分可以生成图片&#xff0c;以下是7个很不错的免费…

YOLOSHOW - YOLOv5 / YOLOv7 / YOLOv8 / YOLOv9 基于 Pyside6 的图形化界面

YOLOSHOW 是一个基于 PySide6&#xff08;Qt for Python&#xff09;开发的图形化界面应用程序&#xff0c;主要用于集成和可视化YOLO系列&#xff08;包括但不限于YOLOv5、YOLOv7、YOLOv8、YOLOv9&#xff09;的目标检测模型。YOLOSHOW 提供了一个用户友好的交互界面&#xff…

一张图带你了解数据分析的完整流程

一个完整的数据分析流程&#xff0c;应该包括以下几个方面&#xff0c;建议收藏此图仔细阅读。 作为数据分析师&#xff0c;无论最初的职业定位方向是技术还是业务&#xff0c;最终发到一定阶段后都会承担数据管理的角色。因此&#xff0c;一个具有较高层次的数据分析师需要…

electron 程序与安装包图标放大与制作

原因 electron-builder 在打包时需要最小支持到256x256像素的icon图标。原有历史图标都太小了。需要尝试将图标放大。 工具 convertio.co/zh/ico-png/ 在线ico转png网站 https://github.com/upscayl/upscayl 图片放大工具 csdn下载 greenfish-icon-editor-pro.en.softonic.c…

分布式ID生成系统之雪花算法详解

在当今的云计算和微服务架构盛行的时代&#xff0c;分布式系统已成为软件开发的重要组成部分。随着系统规模的扩大和业务的复杂化&#xff0c;对数据一致性和唯一性的要求也越来越高&#xff0c;尤其是在全局唯一标识符&#xff08;ID&#xff09;的生成上。因此&#xff0c;分…

mongo和redis的数据备份和还原

redis 安装 Redis安装和基本使用&#xff08;windows版&#xff09; - 知乎 window环境下Redis7服务器的安装和运行_redis7 windows-CSDN博客 备份数据 Redis SAVE 命令用于创建当前数据库的备份。 该命令将在 redis 安装目录中创建dump.rdb文件 查询路径 CONFIG GET dir…

[备赛笔记]——5G大唐杯(5G考试等级考考试基础试题)

个人名片&#xff1a; &#x1f981;作者简介&#xff1a;学生 &#x1f42f;个人主页&#xff1a;妄北y &#x1f427;个人QQ&#xff1a;2061314755 &#x1f43b;个人邮箱&#xff1a;2061314755qq.com &#x1f989;个人WeChat&#xff1a;Vir2021GKBS &#x1f43c;本文由…

0基础学习VR全景平台篇第142篇:VR直播下载流程

大家好&#xff0c;欢迎观看蛙色VR官方——后台使用系列课程&#xff01; 这期&#xff0c;我们将为大家介绍如何下载VR直播内容。 一.如何下载VR直播内容&#xff1f; 首先登录蛙色官网&#xff0c;点击作品管理&#xff1b; 进入作品管理界面后选择全景直播&#xff0c;找到…

常用MII接口详解

开放式系统互连 (OSI) 模型 七层开放系统互连 (OSI) 模型中&#xff0c;以太网层 位于最底部两层 - 物理层和数据链路层。 从百兆以太网接口开始 首先是百兆以太网规定的两种接口 介质无关接口 (MII) Media Independent Interface 介质相关接口 (MDI) Medium Depen…

[Redis]——缓存击穿和缓存穿透及解决方案(图解+代码+解释)

目录 一、缓存击穿&#xff08;热点Key问题&#xff09; 1.1 问题描述 1.2 解决方案及逻辑图 1.2.1 互斥锁 1.2.2 逻辑过期 二、缓存穿透 2.1 问题描述 2.2 解决方案逻辑图 2.2.1 缓存空对象 2.2.2 布隆过滤器 一、缓存击穿&#xff08;热点Key问题&#xff09; 个人理…

web学习笔记(二十六)

目录 1.JS执行队列 1.1JS是单线程 1.2Web Worker 1.3同步和异步 1.4JS执行机制 2.location对象 2.1什么是location对象 2.2url包含的信息 2.3location对象属性 2.4location对象的方法 3.navigator对象和history对象 3.1navigator对象 3.2history对象 1.JS执行队…