深度剖析Linux信号机制

文章目录

  • 信号的概念
  • 信号的分类
  • 信号的产生方式
      • 从键盘获取
      • 通过系统调用
      • 硬件异常
      • 软件条件
  • 如何处理信号的到来
  • 信号的更深入剖析
    • 信号的处理动作是何时进行的?
    • 当有一大批同种信号到来时会怎样?
    • Linux也提供了一批信号相关的系统调用

信号的概念

Linux中的信号是进程异步通信的一种方式。

当某个信号发送到一个进程上,那么该进程就会分析该信号是什么信号,进而做出不同的处理动作。

信号的分类

信号分为两类:不可靠信号与可靠信号。

不可靠信号(1-31):也称为非实时信号,不支持排队,可能会丢失(当相同信号发送多次时,效果相当于发送一次);

可靠信号(34-64):也称为实时信号,支持排队,不会丢失。

本章节只讨论不可靠信号。

image-20230914215256257

信号的产生方式

从键盘获取

比如:

Ctrl + c向进程发送2号信号SIGINT

Ctrl + \向进程发送3号信号SIGQUIT

Ctrl + z向进程发送20号信号SIGTSTP

通过系统调用

比如:

kill系统调用可以向指定进程发送指定信号

kill命令可以向指定进程发送指定信号(kill命令内部就是调用了kill系统调用)

raise函数可以向调用进程发送指定信号(就相当于kill(getpid(), signo)

abort函数可以向调用进程发送6号信号SIGABRT(就相当于kill(getpid(), 6)

硬件异常

比如在代码中进行了除零运算或者野指针访问,那么OS会自动向该进程发送8号信号SIGPIPE或11号信号SIGSEGV

OS是如何知道该进程进行了除零运算或野指针访问的呢?其实CPU中有一个状态寄存器,该寄存器有很多标志位,能够存储当前运算结果的某些特定状态信息(进位、溢出、零值等),OS通过访问该状态寄存器里的标志位,就能够知道当前进程发生了哪些错误进而发送对应的信号。

软件条件

像alarm函数,可以设定一个闹钟,在铃响的时候由OS向调用进程发送14号信号SIGALRM

如何处理信号的到来

当信号到来时,会有三种动作:

  1. 默认处理动作(信号到来时,进行由官方人员写好的处理动作,绝大部分是中止进程)
  2. 忽略动作(信号到来时,对该信号不进行任何处理动作)
  3. 自定义动作(信号到来时,进行自己编写好的处理动作)

只有第三种动作,我们才能让指定信号到来时进行自己想要的动作,那么此时我们就必须有一个函数,能够让我们进行“注册”(对某种信号注册自定义动作)。signal函数就是用来进行注册的。

void handler(int signo) {                                                                            /*自定义动作*/
}
int main() {signal(SIGINT, handler); /*运行注册函数,完成对SIGINT信号的自定义动作的注册*/// 下面就是正常要写的代码while(1);return 0;
}

但是有些信号还是无法进行注册的,比如9号信号SIGKILL

sigaction函数也可以完成上面的操作。

信号的更深入剖析

  • 实际执行信号的处理动作叫做信号递达
  • 信号从产生到递达之间的状态叫做信号未决
  • 一个信号是可以被阻塞的,当该信号被阻塞时,该信号不会进行信号递达,只能保持在信号未决,当阻塞被解除时才会进行信号递达

在进程PCB中有两个位图(pending位图和block位图)

  • pending位图(32位整形):每一个bit位标识了一种信号,bit位上的内容表示该信号是否到来(是否处于信号未决状态)
  • block位图(32位整形):每一个bit位标识了一种信号,bit位上的内容表示该信号是否被阻塞

还有一个函数指针数组:大小为32,每个指针都是对应信号的处理动作

image-20230915084830143

信号的处理动作是何时进行的?

是在内核态转变为用户态的时候!

image-20230915091247721

当我们每次从内核态切换的时候,都会进行一次信号检测,检测pending位图中有没有需要处理的信号,当这些信号的动作是默认动作或者忽略动作时,直接就又返回用户态了。而当这些信号的动作是自定义动作时,会返回用户态执行handler自定义动作,执行完之后,返回内核态,然后再返回用户态。

当有一大批同种信号到来时会怎样?

首先pending位图该标志位置1,然后当信号检测时发现该信号到来了,那么就把该标志位置0同时block的该标志位置1,再去执行该信号的动作,假设该动作持续时间很长(比如handler中一直在循环),然后又有同种信号来了,此时pengding位图此标志位仍然置1,但此时该信号已经被阻塞(屏蔽)了,此后如果一直来同种信号,那么该标志位一直置1。当handler执行完了后,block上的该位会置0(解除该信号的屏蔽),由于在内核态返回用户态的过程中又会进行一次信号检测,此时由于pengding位图中的该标志位置1,block置0,所以又会进行一次该信号的handler动作。

所以,当一大批同种信号到来时,一般会按顺序执行两次该信号的处理动作。

Linux也提供了一批信号相关的系统调用

处理信号集

#include <signal.h>
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset (sigset_t *set, int signo);
int sigdelset(sigset_t *set, int signo);
int sigismember(const sigset_t *set, int signo);

设置block信号集

#include <signal.h>
int sigprocmask(int how, const sigset_t *set, sigset_t *oset);

获取pending信号集

#include <signal.h>
int sigpending(sigset_t *set);

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言——通讯录管理系统

通讯录管理系统项目简介 功能说明 控制台黑窗口实现程序需要满足以下几个功能 程序开始运行时首先显示选择菜单界面&#xff0c;根据用户输入确定实现何种功能 程序界面 代码实现 多文件实现 和之前写的实战项目类似&#xff0c;这里同样采用多文件实现的方式 多文件写代码…

day3_QT

day3_QT 1、文件保存2、始终事件 -闹钟 1、文件保存 2、始终事件 -闹钟 widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimerEvent> #include <QTime> #include <QTextToSpeech>QT_BEGIN_NAMESPACE namespace Ui { clas…

Qt --- Day03

<?xml version"1.0" encoding"UTF-8"?> <ui version"4.0"><class>Widget</class><widget class"QWidget" name"Widget"><property name"geometry"><rect><x>0…

fatal error: linux/compiler-gcc9.h: No such file or directory

linux 找到README文件 cd /mnt/e/CLionProjects/linux-3.10.99 sudo useradd linux3x sudo passwd linux3x sudo mkdir /home/linux3x sudo chown linux3x:linu3x /home/linux3x sudo chmod 755 /home/linux3x su - linux3x mkdir ~/build mkdir ~/build/kernel exit make O/…

目标检测Neck:FPN(Feature Pyramid Network)与PAN(附torch代码)

文章目录 0. 前言1. FPN1.1 FPN核心思想与步骤1.2 FPN的融合过程2. PAN2.1 PANet2.2 原版2.3 mmdetection中yolo_neck版本2.4 nanodet版本ReferenceFPN和PAN都是用于解决在目标检测中特征金字塔网络(FPN)在多尺度检测任务上的不足的方法。下面分别详细介绍一下它们的原理和区别…

Docker 容器设置为自动重启

Docker自动重启原因 Docker自动重启通常是由以下几个原因导致的&#xff1a; 程序崩溃系统内存不足系统进程使用过多CPU和RAM导致的阻塞docker容器被杀死或重新启动&#xff0c;导致应用程序中断网络中断 当这些问题出现时&#xff0c;Docker会自动重启运行中的服务来尝试解…

malloc与free

目录 前提须知&#xff1a; malloc&#xff1a; 大意&#xff1a; 头文件&#xff1a; 申请空间&#xff1a; 判断是否申请成功&#xff1a; 使用空间&#xff1a; 结果&#xff1a; 整体代码&#xff1a; malloc申请的空间怎么回收呢? 注意事项&#xff1a; free:…

【入门篇】ClickHouse最优秀的开源列式存储数据库

文章目录 一、什么是ClickHouse&#xff1f;OLAP场景的关键特征列式数据库更适合OLAP场景的原因输入/输出CPU 1.1 ClickHouse的定义与发展历程1.2 ClickHouse的版本介绍 二、ClickHouse的主要特性2.1 高性能的列式存储2.2 实时的分析查询2.3 高度可扩展性2.4 数据压缩2.5 SQL支…

PHP自己的框架2.0结合容器技术(重构篇二)

目录 1、使用容器实现框架加载类运行 2、 创建框架容器类core/fm/Di.php 3、框架使用容器类来执行public/index.php 4、运行效果还是一样 1、使用容器实现框架加载类运行 2、 创建框架容器类core/fm/Di.php 什么是容器&#xff1f;容器就相当于盒子&#xff0c;把很多类放里…

Postman应用——控制台调试

当你在测试脚本中遇到错误或意外行为时&#xff0c;Postman控制台可以帮助你识别&#xff0c;通过将console.log调试语句与你的测试断言相结合&#xff0c;你可以检查http请求和响应的内容&#xff0c;以及变量之类的。 通常可以使用控制台日志来标记代码执行&#xff0c;有时…

【分布式】分布式ID

目录 前言一、雪花算法snowflake1. 组成2. 优缺点3. 时钟回拨怎么解决a. 时钟回拨b. 解决方案 4. 项目中如何使用 二、基于Redis三、基于Zookeeper四、号段模式五、指定步长的自增ID六、UUID参考 六、扩展总结 前言 分布式场景下&#xff0c;一张表可能分散到多个数据结点上。因…

【JavaEE】多线程案例-单例模式

文章目录 1. 前言2. 什么是单例模式3. 如何实现单例模式3.1 饿汉模式3.2 懒汉模式4. 解决单例模式中遇到的线程安全问题4.1 加锁4.2 加上一个判断解决频繁加锁问题4.2 解决因指令重排序造成的线程不安全问题 1. 前言 单例模式是我们面试中最常考到的设计模式。什么是设计模式呢…

【Redis】深入探索 Redis 主从结构的创建、配置及其底层原理

文章目录 前言一、对 Redis 主从结构的认识1.1 什么是主从结构1.2 主从结构解决的问题 二、主从结构创建2.1 配置并建立从节点2.2.1 从节点配置文件2.2.2 启动并连接 Redis 主从节点2.2.3 SLAVEOF 命令2.2.4 断开主从关系 2.2 查看主从节点的信息2.2.1 INFO REPLICATION 命令2.…

《DevOps实践指南》- 读书笔记(六)

DevOps实践指南 Part 4 第二步 &#xff1a;反馈的技术实践17. 将假设驱动的开发和A/B测试融入日常工作17.1 A/B 测试简史17.2 在功能测试中集成 A/B 测试17.3 在发布中集成 A/B 测试17.4 在功能规划中集成 A/B 测试17.5 小结 18. 建立评审和协作流程以提升当前工作的质量18.1 …

04条件构造器和常用接口

条件构造器和常用接口 wapper介绍 条件构造器的两个条件之间默认就是AND并列关系,如果需要或者的关系则需要调用构造器的or()方法 条件构造器类型作用Wrapper条件构造抽象类,最顶端父类AbstractWrapper生成SQL的where条件QueryWrapper封装查询或删除的条件UpdateWrapper封装修…

小程序自定义tabbar

前言 使用小程序默认的tabbar可以满足常规开发&#xff0c;但是满足不了个性化需求&#xff0c;如果想个性化开发就需要用到自定义tabbar,以下图为例子 一、在app.json配置 先按照以往默认的形式配置&#xff0c;如果中间的样式特殊则不需要配置 "tabBar": {&qu…

社区分享|MeterSphere变身“啄木鸟”,助力云帐房落地接口自动化测试

云帐房网络科技有限公司&#xff08;以下简称为“云帐房”&#xff09;成立于2015年3月&#xff0c;以“成为最值得信赖的税务智能公司”为愿景&#xff0c;运用人工智能、大数据等互联网技术&#xff0c;结合深厚的财税行业服务经验&#xff0c;为代账公司和中大型企业提供智能…

避雷器雷击计数器检验

试验目的 由于密封不良&#xff0c; 放电计数器在运行中可能进入潮气或水分&#xff0c; 使内部元件锈蚀&#xff0c;导致计数器不能正确动作&#xff0c; 因此需定期试验以判断计数器是否状态良好、 能否正常动作&#xff0c; 以便总结运行经验并有助于事故分析。 带有泄漏电…

小程序隐私弹窗的实现

小程序的开发者对于微信官方来说是有爱有恨&#xff0c;三天二头整事是鹅厂的一贯风格。 隐私弹窗的几个要点 回归正题&#xff0c;小程序隐私弹窗的几个要点&#xff1a; 1、何时弹出用户隐私协议的弹窗&#xff1f; 2、是每次进小程序都弹出来吗&#xff1f; 这两个想明…

什么是HTTP状态码?常见的HTTP状态码有哪些?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 什么是HTTP状态码&#xff1f;⭐ 1xx - 信息性状态码⭐ 2xx - 成功状态码⭐ 3xx - 重定向状态码⭐ 4xx - 客户端错误状态码⭐ 5xx - 服务器错误状态码⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前…