Linux——信号(2)

在上一张博客我们介绍了Linux中信号的概念和信号是如何产生的,虽然信号
有多种产生方式,但是最终只能由操作系统给对应进程发送特定信号。现在
我将更加规范的介绍Linux中的信号。

上一章的遗留问题

我们上一章中在观察信号的默认处理的时候发现终止信号的种类可以分为两种,Term和Core:
在这里插入图片描述
我们可以发现Core类信号产生的异常错误的严重程度是要高于Term类型的。而且出现了Core类错误时,我们在修复错误时往往是需要修改代码本身的。所以Core类型的信号在被处理时,同时也会生成一个文件,这个文件的文件名包含Core和出现异常的进程pid,这个文件保存了进程出异常时,进程中的一些重要的数据:
如果是使用虚拟机的小伙伴可能会观察到这种文件。但是使用云服务器的小伙伴可能并没有见过这种文件,我们可以使用ulimit -a查看系统的一些配置的大小,在云服务器上:
在这里插入图片描述
可以看到云服务器上这个文件的大小被设置成了0,那也就是相当于不生成这种文件。而在虚拟机中这个文件的大小不一定是被设置成了0。我们可以使用ulimit -c来修改这个文件配置的大小:
在这里插入图片描述
我们设置好文件配置的大小之后我们写一段代码:
在这里插入图片描述
我们再重新起一个shell然后再运行这个程序,再本来这个shell上也运行一遍:
新的shell进程上:
在这里插入图片描述
可见它并没有生成什么包含core和进程pid的文件。
本来的shell进程上:
在这里插入图片描述
它生成了这样的一个文件,那为什么新起的shell进程上没有生成呢?我们发现在新起的shell进程上:
在这里插入图片描述
它的大小仍旧是0,至此我们可以得出使用ulimit -c修改的配置文件的大小,它的作用效果是随shell进程的。
那么这个文件有什么用呢?我们打开它可以看到它就是二进制:
在这里插入图片描述
我们说了,它其中会记录进程中的一些重要的数据。这使得我们可以使用gdb来便捷的定位到哪句代码出了问题:
在这里插入图片描述
这种技术叫做核心转储。
那么为什么云服务器会将它的大小设置为0不让它生成呢?我们可以看到,这个文件是比较大的,假如我们多生成几个呢?
在这里插入图片描述
这还只是一行代码,如果是公司企业中的服务器代码呢?我们都知道服务器中的服务上线之后,会有运维人员来保证服务器中服务的正常运行,而现在也有自动化运维,它可以在进程异常退出之后,可以重新让这个服务跑起来,那么此时此刻对于我们现在这个代码,它每一次启动都会带来那么大的文件,我们的代码可能一秒就启动上千次,那么这样的话,我们的磁盘用不了多久就被写满了,这对我们要修复异常的服务就更加的困难了,磁盘满了之后我们一般是对这台机器做不了任何操作了。

1. 一些规范的名词

信号递达:实际执行信号的处理动作
信号未决:信号从产生到递达之间的状态
阻塞:处于信号未决和信号递达之间的状态,其实也是一直处于信号未决状态,直到信号
被停止阻塞,然后才会递达

信号递达其实就是处理信号,普通信号的信号是不会叠加的,它产生多少次也只算一次,递达前后未决状态就会被取消,无论之前有多少次信号未决,这也跟位图本身的特性有关。
信号未决其实就是信号的产生也就是task_struct结构体中的信号位图被写入
我们以前介绍过,对于信号的处理方式有三种:默认处理,忽略,自定义捕捉。其中我们要清楚忽略它本身也是对于信号的处理方式(例如老师布置了作业之后,你选择视而不见这本身也是对这件事情的一个处理方式,你听到了老师布置作业叫做信号未决,你写作业就叫做信号递达。你对老师布置作业这条消息视而不见忽略也叫做信号递达,因为你处理了这个信号)。
有些人会将忽略和阻塞混淆成一个东西这是不对的,阻塞是只要信号只要被阻塞后就不会被递达,而忽略是这个信号已经递达了。两者截然不同。
在前面我介绍了信号的自定义捕捉使用signal接口,这里我介绍信号的默认处理以及忽略,它们是由两个宏实现的:
信号默认处理:
在这里插入图片描述
在这里插入图片描述
在这段代码中我们开始将二号信号设置成自定义捕捉,在信号递达时将进行我们自定义的函数,会打印出如上结果,但是当cnt–到小于0时我们将2号信号更改为默认处理,此时我们ctrl + c就会直接退出进程,其中SIG_DFL就是将信号设置成默认处理方式的宏。
忽略处理:
在这里插入图片描述
在这里插入图片描述
SIG_IGN是将信号忽略的宏,可以看到当我们使用ctrl + c的组合键终止进程的时候并没有任何反应,使用ctrl + \才终止了进程。
观察这两个宏的定义其实它们就是强转而已:
在这里插入图片描述

2. 内核数据结构

a. 内核数据结构

我们在之前学会了如何对信号进行自定义捕捉也就是信号递达,但是我们对信号未决的认识并不是那么那么清楚,其实在内核数据结构中,我们的task_struct关于信号维护着这么些东西:
在这里插入图片描述
其中hander表就是一个函数指针数组,下标对应着信号的编号,其中有着对应信号的处理方式。而pending表就是信号产生时要被写入的位图表,block是从结构上与pending表一模一样的,不同的是:
pending中的位表示信号的编号,pending的内容表示信号是否未决。
而block中的位表示信号的编号,block的内容表示是否都阻塞该信号。
我们学会了信号递达的处理方式,现在我们要来学习关于信号未决和信号阻塞。其中主要是信号阻塞,因为信号未决也就是我前面介绍的信号的产生方式嘛。
对于block表和pending表它们其实都是位图,而在Linux中,给出了这样的结构:
在这里插入图片描述
在这里插入图片描述
sigset_t这种类型叫做信号集
其中block表也叫做阻塞信号集,当前进程的信号屏蔽字

b. 信号集操作函数

那么我们如何对这个位图进行操作呢?难道得自己造轮子吗其实操作系统早就帮我们造好了:
在这里插入图片描述
下面我们来介绍一下,这些对sigset_t类型的位图操作的函数

1. sigemptyset:清空set(全部置零,也就是初始化)
2. sigfillset:全部置一
3. sigaddset:将目标信号对应位图的位置置一
4. sigdelset:将目标信号对应位图的位置置零
5. sigismember:检测目标信号是否在set表中

c. block操作接口

了解了关于sigset_t类型的操作后,我们再来认识关于对block表的操作接口,其实就一个
sigprocmask:
在这里插入图片描述
其中第一个参数是操作方式:

1. SIG_BLOCK:set包含了我们希望添加到当前信号屏蔽字的信号
2. SIG_UNBLOCK:set包含了我们希望从当前信号屏蔽字中解除阻塞的信号
3. SIG_SETMASK:设置当前信号屏蔽字位为set所指向的值,即block表 = set

第二个参数是我们要设置的set表
第三个参数是被更新前的block表,是一个输出型参数。

d. pending表接口

关于pending表其实就是信号的产生,我们之前已经介绍过了,所以这里只有一个接口,那就是获取pending表:
在这里插入图片描述
可以看到它有一个输出型参数。
有了这些接口之后,我们就可以写出代码来观测,内核数据结构的表现了:

e. 代码展示

在这里插入图片描述

在这里插入图片描述

我们可以看到当启动进程的时候,我们按下ctrl + c之后,信号未决后就信号递达了,五秒过后,我们阻塞了二号信号,此时按下ctrl + c之后,虽然pending表中二号信号处于信号未决的状态,但是它无法信号递达,当再过五秒之后取消对二号信号的阻塞,二号信号立即递达,递达的同时pending表中对应二号信号的信号未决状态也取消了。
附上代码:

#include <iostream>
#include <string>
#include <cstdlib>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>using namespace std;void sighander(int signo)
{cout << "获得了" << signo << "号信号" << endl;
}void PrintPending()
{sigset_t pending;sigpending(&pending); // 获取pending表for(int i = 31; i > 0; i--){if(sigismember(&pending, i)) // 利用该函数判断特定信号是否存在于pending表中,存在则打印1,不存在打印0{cout << 1;}else cout << 0;}cout << endl;
}int main()
{sigset_t set, oset;// 将要使用的set表初始化sigemptyset(&set);sigemptyset(&oset);signal(2, sighander); // 对2好信号自定义捕捉int cnt = 5;while(true){PrintPending(); // 打印pending表sleep(1);cnt--;if(cnt == 0){sigaddset(&set, 2);sigprocmask(SIG_BLOCK, &set, &oset); // 对2号信号进行阻塞cout << "屏蔽了二号信号" << endl;}if(cnt == -5){sigprocmask(SIG_SETMASK, &oset, &oset); // 取消对2号信号的阻塞cout << "取消屏蔽二号信号" << endl;}}return 0;
}

还有人会有疑问,那就是到底是信号未决状态的取消是在信号递达开始前还是完成后呢?在信号递达的时候显然是不可能的,因为当自定义捕捉时,我们可没有取消信号未决状态。
一个简单的代码可以看到:

#include <iostream>
#include <string>
#include <cstdlib>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>using namespace std;void PrintPending()
{sigset_t pending;sigpending(&pending); // 获取pending表for(int i = 31; i > 0; i--){if(sigismember(&pending, i)) // 利用该函数判断特定信号是否存在于pending表中,存在则打印1,不存在打印0{cout << 1;}else cout << 0;}cout << endl;
}void sighander(int signo)
{PrintPending();cout << "获得了" << signo << "号信号" << endl;
}int main()
{signal(2, sighander);while(true){cout << "running..." << endl;sleep(1);}return 0;

在这里插入图片描述
可以看到在信号递达前就已经解除信号未决状态了。

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

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

相关文章

canal监听binlog记录业务数据的变更;canalAdmin对instance做web配置

概述 平时在开发中会通过logback打印一些开发日志&#xff0c;有时也会需要记录一些业务日志&#xff0c;简单的就直接用log记录一下&#xff0c;但是系统中需要记录日志的地方越来越多时&#xff0c;不能每个地方都写一套log记录&#xff1b; 由于平常用的大多都是mysql&…

【论文阅读笔记】Contrastive Learning with Stronger Augmentations

Contrastive Learning with Stronger Augmentations 摘要 基于提供的摘要&#xff0c;该论文的核心焦点是在对比学习领域提出的一个新框架——利用强数据增强的对比学习&#xff08;Contrastive Learning with Stronger Augmentations&#xff0c;简称CLSA&#xff09;。以下…

【Jvm】性能调优(上)线上问题排查工具汇总

文章目录 一.互联网概念1.产品闭环和业务闭环2.软件设计中的上游和下游3.JDK运行时常量池 二.CPU相关概念1.查询CPU信息2.CPU利用率&#xff08;CPU utilization&#xff09;和 CPU负载&#xff08;CPU load&#xff09;2.1.如何理解CPU负载2.2.top命令查看CPU负载均值2.3.CPU负…

Pytorch 配置 GPU 环境

1、Pytorch 深度学习跑代码的时候&#xff0c;因为简单的操作不适合cpu运行&#xff0c;我们更习惯用GPU加速代码。 本章将介绍怎么安装pytorch的gpu环境&#xff0c;以及常见的问题 关于conda的安装&#xff0c;参考之前文章&#xff1a;深度学习环境配置&#xff1a;Anaco…

初始树莓派 + VMware17 安装树莓派(Raspberry Pi 4B/5)

文章目录 树莓派入门 VMware17 安装树莓派(Raspberry Pi 4/5B)前言一、树莓派入门指南&#xff1a;从零开始探索树莓派树莓派4B和5对比 二、在VMware Workstation 17上安装树莓派4B/5操作系统&#xff1a;实现强大性能与便捷模拟工具准备开始安装树莓派1.创建一个虚拟机2. 选择…

PyCharm 取消所有断点

PyCharm 取消所有断点 1. Run -> View Breakpoints...2. Python Line Breakpoint3. Remove - DoneReferences 1. Run -> View Breakpoints… 2. Python Line Breakpoint ​​​ 3. Remove - Done References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/

【web安全】渗透测试实战思路

步骤一&#xff1a;选目标 1. 不建议太小的公司&#xff08;可能都是请别人来开发的&#xff0c;用现成成熟的框架&#xff09; 2. 不建议一线大厂&#xff1a;腾讯&#xff0c;字节&#xff0c;阿里等&#xff0c;你懂的 3. 不建议政府部门&#xff0c;安全设备多&#xff…

Spring MVC(基于 Spring4.x)基础学习

一、SpringMVC概述 二、SpringMVC的HelloWorld 三、使用RequestMapping映射请求 四、映射请求参数&请求头 五、处理模型数据 六、视图和视图解析器 七、RESTful CRUD 八、SpringMVC表单标签&处理静态资源 九、数据转换&数据格式化&数据校验 十、处理JSON:使用…

前端win10如何设置固定ip(简单明了)

1、右击这个 2、点击属性 3、双击协议版本4设置成以下就ok

原生微信小程序开发记录

1. 拿到项目 先构建 2.小程序与普通网页开发的区别 网页开发渲染线程和脚本线程是互斥的&#xff0c;这也是为什么长时间的脚本运行可能会导致页面失去响应&#xff0c;而在小程序中&#xff0c;二者是分开的&#xff0c;分别运行在不同的线程中。网页开发者可以使用到各种浏览…

【HarmonyOS】鸿蒙开发之Slider组件——第3.5章

组件应用场景: 设备音量大小&#xff0c;调节屏幕亮度等需求 slider组件内options属性简介 value&#xff1a;滑动条当前进度值。 min&#xff1a;设置滑动条设置最小值。 max&#xff1a;设置滑动条设置最大值&#xff0c;默认为 100 。 step&#xff1a;设置滑动条滑动跳动…

Python从进阶到高级—通俗易懂版

Python从进阶到高级—通俗易懂版 # # Author : Mikigo # Time : 2021/12/23 # 一、简介 Python 进阶是我一直很想写的&#xff0c;作为自己学习的记录&#xff0c;过去自己在看一些代码的时候经常会困惑&#xff0c;看不懂&#xff0c;然后自己去查资料、看书籍&#xff0…

JAVA之HashMap详解

HashMap 1. 设计原理 HashMap 基于哈希表的 Map 接口实现&#xff0c;是以 key-value 存储形式存在&#xff0c;即主要用来存放键值对。HashMap 的实现不是同步的&#xff0c;这意味着它不是线程安全的。它的 key、value 都可以为 null&#xff0c;此外&#xff0c;HashMap 中…

appium实现自动化测试原理

目录 1、Appium原理 1.1、Android Appium原理图文解析 1.1.2、原理详解 1.1.2.1、脚本端 1.1.2.2、appium-server 1.1.2.3、中间件bootstrap.jar 1.1.2.4、驱动引擎uiautomator 1.2、 IOS Appium原理 1、Appium原理 1.1、Android Appium原理图文解析 执行测试脚本全过…

C#,二进制数的按位交换(Bits swap)的算法与源代码

数字在指定位置指定位数的交换是常见算法。 1 源程序 using System; using System.Text; using System.Collections; using System.Collections.Generic; namespace Legalsoft.Truffer.Algorithm { public static partial class Algorithm_Gallery { /// <…

专业140+总分420+南京信息工程大学811信号与系统考研经验南信大电子信息与通信工程,真题,大纲,参考书

今年顺利被南信大电子信息录取&#xff0c;初试420&#xff0c;专业811信号与系统140&#xff08;Jenny老师辅导班上140很多&#xff0c;真是大佬云集&#xff09;&#xff0c;今年应该是南信大电子信息最卷的一年&#xff0c;复试线比往年提高了很多&#xff0c;录取平均分380…

扭蛋机小程序开发:发展优势

商场中精美的扭蛋机一直都是年轻人的心头好&#xff0c;目前&#xff0c;扭蛋机商品也不在局限于各种小型玩具&#xff0c;也逐渐与各类热门IP合作&#xff0c;打造出了各类手办、周边等&#xff0c;深受各个年龄层的喜爱。 如今&#xff0c;扭蛋机在互联网的推动下&#xff0…

算法的基本概念

设么是算法&#xff1f; 什么是好的算法/ 什么是算法&#xff1a; 量水的问题&#xff1a; 方案如下&#xff1a;&#xff08;核心思路就是两个桶差值为2&#xff0c;两次差值为4&#xff0c;7-(5-4) 6&#xff09; 算法&#xff1a;准确描述的 “操作步骤 (问题求解步骤)”&…

数据结构中图的概念以及遍历算法的实现

在数据结构中&#xff0c;图&#xff08;Graph&#xff09;是由节点&#xff08;Vertex&#xff09;和连接节点的边&#xff08;Edge&#xff09;组成的一种非线性数据结构。图可以用来表示各种实际问题中的关系和连接&#xff0c;如社交网络、道路网络、电路等。 图由两个主要…

2023年全球架构师峰会(ArchSummit北京站2023):核心内容与学习收获(附大会核心PPT下载)

本次峰会是一场集结了全球顶级技术专家和行业领袖的盛会。作为一年一度的重要技术交流活动&#xff0c;本次峰会聚焦当前及未来软件架构的发展趋势、技术挑战与创新实践&#xff0c;旨在为参会者提供一个深度交流、学习与合作的平台。在为期两天的会议中&#xff0c;与会者不仅…