【Linux】:信号在内核里的处理

信号的发送和保存

  • 一.内核中的信号处理
  • 二.信号集操作函数
    • 1.一些信号函数
    • 2.sigprocmask
    • 3.sigpending
    • 4.写代码
  • 三.信号在什么时候处理的
  • 四.再谈地址空间

一.内核中的信号处理

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

信号方法运行->handler表

普通信号【1-31】每一个都需要有自己的处理方法。这些方法分别是一个函数,而所有函数的指针都存在一个函数指针数组里(handler_t handler[31])。

在这里插入图片描述

信号阻塞->block表

再说说信号阻塞,其实顾名思义就是暂时把信号屏蔽,到合适的时候再将屏蔽解除,读取信号。在handler表和task_struct之间还有一张block表来标识是否屏蔽该信号。(注意屏蔽是一种状态与是否产生信号无关)

是否收到信号以及收到哪些信号->pending表

在这里插入图片描述

总结

1.每个信号都有两个标志位分别表示阻塞(block)和未决(pending),还有一个函数指针表示处理动作。信号产生时,内核在进程控制块中设置该信号的未决标志,直到信号递达才清除该标志。在上图的例子中,SIGHUP信号未阻塞也未产生过,当它递达时执行默认处理动作。
2.SIGINT信号产生过,但正在被阻塞,所以暂时不能递达。虽然它的处理动作是忽略,但在没有解除阻塞之前不能忽略这个信号,因为进程仍有机会改变处理动作之后再解除阻塞。
3.SIGQUIT信号未产生过,一旦产生SIGQUIT信号将被阻塞,它的处理动作是用户自定义函数sighandler。
4.如果在进程解除对某信号的阻塞之前这种信号产生过多次,将如何处理?POSIX.1允许系统递送该信号一次或多次。Linux是这样实现的:常规信号在递达之前产生多次只计一次,而实时信号在递达之前产生多次可以依次放在一个队列里。
5.信号处理实际上就是检测这三张表。

一个例子

在这里插入图片描述

在这里插入图片描述

将2号信号忽略后,操作系统就将handler表的2号信号的位置的操作方法变为忽略.

二.信号集操作函数

我们知道信号处理要经过三张表,毫无疑问这三张表是存在操作系统里的。想要从操作系统里获取信息,那么必定需要经过系统调用接口。

sigset_t类型

从上图来看,每个信号只有一个bit的未决标志,非0即1,不记录该信号产生了多少次,阻塞标志也是这样表示的。因此,未决和阻塞标志可以用相同的数据类型sigset_t来存储,sigset_t称为信号集,这个类型可以表示每个信号的“有效”或“无效”状态,在阻塞信号集中“有效”和“无效”的含义是该信号是否被阻塞,而在未决信号集中“有效”和“无效”的含义是该信号是否处于未决状态。 阻塞信号集也叫做当前进程的信号屏蔽字(Signal Mask),这里的“屏蔽”应该理解为阻塞而不是忽略。下面将详细介绍信号集的各种操作。

1.一些信号函数

sigset_t类型对于每种信号用一个bit表示“有效”或“无效”状态,至于这个类型内部如何存储这些bit则依赖于系统实现,从使用者的角度是不必关心的,使用者只能调用以下函数来操作sigset_t变量,而不应该对它的内部数据做任何解释,比如用printf直接打印sigset_t变量是没有意义的。

在这里插入图片描述

1函数sigemptyset初始化set所指向的信号集,使其中所有信号的对应bit清零,表示该信号集不包含 任何有效信号。
2.函数sigfillset初始化set所指向的信号集,使其中所有信号的对应bit置位,表示 该信号集的有效信号包括系统支持的所有信号。
3.注意,在使用sigset_ t类型的变量之前,一定要调 用sigemptyset或sigfillset做初始化,使信号集处于确定的状态,初始化sigset_t变量之后就可以在调用sigaddset和sigdelset在该信号集中添加或删除某种有效信号。

2.sigprocmask

调用函数sigprocmask可以读取或更改进程的信号屏蔽字(阻塞信号集)。

在这里插入图片描述

第一个参数:

在这里插入图片描述

第二个参数:自己创建的block表。

第三个参数:它是一个输出型参数,它会保存原始的block表(调用函数之前的表)。

3.sigpending

在这里插入图片描述

它是一个输出型函数。它的功能非常简单就是把我们pending表里所有的二进制序列带出,方便我们做检查。

总结:signal函数对应handler表,sigprocmask函数对应block表,sigpending函数对应pending表。

4.写代码

代码思路:将2号信号的block表设为阻塞,不断获取pending表,在初始状态pending表内应全为0,紧接着使用ctrl+c(发送2号信号),可以看到一瞬间pending表里一个数字变为了1(表示为递达)。

在这里插入图片描述

在这里插入图片描述

三.信号在什么时候处理的

前面说到信号会在合适的时间进行处理,那么合适的时间究竟是什么时候呢?

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

在这里插入图片描述

我们在调用系统调用时,很明显要陷入操作系统里,但进入操作系统是需要资格的,这时我们的身份就会变为内核态,当调用完毕后又会切回用户态。

四.再谈地址空间

在谈虚拟地址时,我们一般说什么共享区,代码区,常量区…其实都是在谈虚拟地址的一部分,还有一部分是内核空间,顾名思义就是访问系统调用的空间。虚拟地址映射到物理内存有页表,内核空间映射到物理内存也有内核级页表。与普通页表不同的是,每一个进程都有自己的普通页表,而内核级页表只有一张,也就是说系统调用函数的地址其实是固定的。

在这里插入图片描述

那么操作系统是怎么知道你是否进入了内核态呢?其实是因为寄存器,在CPU里有一个ecs寄存器,它的低两位就用来表示用户态和内核态,0表示内核态,3表示用户态。

在这里插入图片描述

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

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

相关文章

『 Linux 』僵尸进程与孤儿进程

文章目录 🚀僵尸进程 - Z(zomble)🛰️ 僵尸状态与死亡状态的区别 🛰️🛰️ 僵尸状态的危害 🛰️ 🚀孤儿进程🛰️ 为什么托孤 🛰️ 🚀僵尸进程 - Z(zomble) 一个进程的创…

米贸搜| Youtube运营:免费涨粉的16个技巧

1、要求观众订阅你的频道 要求用户订阅你的频道无非是再简单不过的方法了,有时你需要做的只是一个及时的提醒而已。红色的订阅按钮通常很难被忽略,但是你可能还需要提醒用户点击订阅按钮旁边的“铃铛”图标,以打开消息提醒,以便在…

vue找依赖包的网址

https://www.npmjs.com/ 浅收藏一下

心大数据结构题型

选择题 2021 数据处理的单位:数据元素 矩阵压缩存储 2022 ①单链表头插法选择 ②矩阵压缩存储,行优先 ③删除链表节点的时间复杂度 ④稀疏矩阵存储 ⑤平衡二叉树时间复杂度 ⑥栈和队列的出队,问栈的大小至少多少 ⑦拓扑排序 ⑧参考书 360…

30.0/集合/ArrayList/LinkedList

目录 30.1什么是集合? 30.1.2为什么使用集合 30.1.3自己创建一个集合类 30.1.3 集合框架有哪些? 30.1.2使用ArrayList集合 30.2增加元素 30.3查询的方法 30.4删除 30.5 修改 30.6泛型 30.1什么是集合? 我们之前讲过数组,数组中它也可以存放多个元素。集合…

关于torch.backends.cudnn.benchmark = True

cuDNN 是英伟达专门为深度神经网络所开发出来的 GPU 加速库,针对卷积、池化等等常见操作做了非常多的底层优化,比一般的 GPU 程序要快很多。大多数主流深度学习框架都支持 cuDNN,PyTorch 自然也不例外。在使用 GPU 的时候,PyTorch…

Cenos7系统通过链接一键安装LAMP项目环境(linux,apache,mysql,php)

前言:嫌装环境麻烦,以下介绍自动安装环境的方法 一.环境配置 根据自己需要选择 操作系统:CenOS 7.x以上Web服务器:Apache 2.4数据库:MySQL 5.7开发框架:ThinkPHP 5.0(PHP5.0以上)…

CountDownLatch和CyclicBarrier源码详解

其他系列文章导航 Java基础合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、CountDownLatch和CyclicBarrier 二、CountDownLatch源码分析 三、CyclicBarrier源码分析 四、总结 前言 我现在有个场景:现在我有50个任务&…

【Web】NewStarCtf Week2 个人复现

目录 ①游戏高手 ②include 0。0 ③ez_sql ④Unserialize? ⑤Upload again! ⑥ R!!C!!E!! ①游戏高手 经典前端js小游戏 检索与分数相关的变量 控制台直接修改分数拿到flag ②include 0。0 禁了base64和rot13 尝试过包含/var/log/apache/access.log,ph…

Git 入门指南

什么是 Git? Git 的目前最流行的分布式版本控制软件,可以帮助我们高效敏捷的处理任何项目。 版本管理 要理解 Git 我们首先要理解版本管理。 版本管理就是开发过程中用于管理对文件、目录或者工程等内容的修改历史,可以让我们方便的查看历史…

java学习part20内部类

116-面向对象(高级)-类的成员之五:内部类_哔哩哔哩_bilibili 1.内部类

在Anaconda中用命令行安装环境以及安装包

一、下载Anaconda 下载地址 二、创建环境 1. 打开Anaconda命令行 2.创建环境 conda create -n 环境名称 python3.10(需要的python版本号) 3.激活环境 activate 环境名4.下载安装包 pip install 模块名 -i https://pypi.tuna.tsinghua.edu.cn/simple5.下载torch 官网&…

Python语言学习笔记之三(字符编码)

本课程对于有其它语言基础的开发人员可以参考和学习,同时也是记录下来,为个人学习使用,文档中有此不当之处,请谅解。 什么是字符编码 计算机从本质上来说只认识二进制中的0和1,字符编码(Character Encoding) 是一种将…

大数据-之LibrA数据库系统告警处理(ALM-37006 Coordinator进程异常)

告警解释 当出现如下情况时,产生该告警: CN所在机器发生硬件故障(断电、硬盘损坏等)。CN实例数据目录中的postgresql.conf配置文件不存在或者其中某个配置参数不正确。CN实例线程无法监听IP,或者无法绑定监听端口。C…

【Makefile】和【CMake】的区别

Makefile 和 CMake 的区别 Makefile 和 CMake 都是用于构建项目的工具,但它们有一些区别。 Makefile: 语法: Makefile 使用自己的语法规则,包括规则、目标、依赖等。这是一种特定于 make 工具的语法。 平台依赖: Makefile 是平…

【JavaScript框架】Vue与React中的组件框架概念

组件框架是用于构建应用程序的工具,以便将UI和逻辑划分为单独的可重用组件。目前的组件框架包括React、Vue、Angular、Ember、Svelte等。 Vue和React使用了常见的框架概念,如处理状态、道具、引用、生命周期挂钩、事件等。这两个框架在当今的web开发中被…

案例:某电子产品电商平台借助监控易保障网络正常运行

一、背景介绍 某电子产品电商平台是一家专注于电子产品销售的电商平台,拥有庞大的用户群体和丰富的产品线。随着业务规模的不断扩大,网络设备的数量和复杂性也不断增加,网络故障和性能问题时有发生,给平台的稳定运行带来了很大的挑…

项目中高并发如何处理

在项目中处理高并发主要需要考虑以下几个方面的策略: 优化数据库设计:使用合适的数据结构、索引和查询优化技术可以显著提高数据库的响应性能;分库分表使用缓存:缓存是一种非常有效的处理高并发的方法。通过将常用的数据或结果保…

[原创][第I部分][编程基础]我的C++ 98复习并升级到C++20的复习旅途

[简介] 常用网名: 猪头三 出生日期: 1981.XX.XXQQ: 643439947 个人网站: 80x86汇编小站 https://www.x86asm.org 编程生涯: 2001年~至今[共22年] 职业生涯: 20年 开发语言: C/C、80x86ASM、PHP、Perl、Objective-C、Object Pascal、C#、Python 开发工具: Visual Studio、Delphi…

python激活python38

py38是我建立的anaconda下的一个python3.8环境。 命令行里使用conda activate py38会出现: conda activate error: argument COMMAND: invalid choice 因为condat已经移除了该命令。 执行 activate py38没报错,但是没有转换到py38环境。 使用 sour…