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表也叫做阻塞信号集,当前进程的信号屏蔽字
其中9号信号和19号信号是不可被屏蔽的。

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.mfbz.cn/a/397628.html

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

相关文章

新增长100人研讨会:快消零售专场探讨招商加盟数字化转型实战

2024年2月2日下午&#xff0c;一场由纷享销客与杨国福集团联合主办的招商加盟数字化转型研讨会在上海成功举办。本次研讨会汇聚了众多快消零售业界的领军人物&#xff0c;共同探讨行业未来的新增长点。 会议伊始&#xff0c;杨国福集团数字化中心负责人王林林发表了主题演讲&a…

基于Springboot+Vue的在线考试系统源码

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 随着现代教育和职业培…

【Vuforia+Unity】AR03-圆柱体物体识别

1.创建数据库模型 这个是让我们把生活中类似圆柱体和圆锥体的物体进行AR识别所选择的模型 Bottom Diameter:底部直径 Top Diameter:顶部直径 Side Length:圆柱侧面长度 请注意&#xff0c;您不必上传所有三个部分的图片&#xff0c;但您需要先为侧面曲面关联一个图像&#…

今日Arxiv最热NLP大模型论文:浙江大学发布统一的幻觉检测框架UNIHD

引言&#xff1a;多模态大语言模型的幻觉问题及其重要性 在人工智能领域&#xff0c;多模态大语言模型&#xff08;MLLMs&#xff09;已经取得了显著的进步&#xff0c;它们在多种任务中展现出了类似人类认知和学习的能力&#xff0c;为人工通用智能&#xff08;AGI&#xff0…

【Java大数据期末】银行管理系统(MySQL数据库)

诚接C语言、C、Java、Python、HTML、JavaScript、vue、MySQL相关编程作业&#xff0c; 标价10-20每份&#xff0c;如有需要请加文章最下方QQ。 本文资源&#xff1a;https://download.csdn.net/download/weixin_47040861/88850902https://download.csdn.net/download/weixin_4…

ClickHouse--06--其他扩展MergeTree系列表引擎

其他扩展MergeTree系列 MergeTree 系列表引擎 --种类 MergeTree 系 列 表 引 擎 包 含 &#xff1a; MergeTreeReplacingMergeTreeSummingMergeTree&#xff08;汇总求和功能&#xff09;AggregatingMergeTree&#xff08;聚合功能&#xff09;CollapsingMergeTree&#xff08…

maven3下载地址(含旧版本)

因为现有的3.8版本与IDEA不兼容&#xff0c;我需要下载3.6版本&#xff0c;但是官网的位置非常隐蔽&#xff0c;找了很多资料才看到。故记录一下。Index of /dist/maven/maven-3 选择需要的版本 选择binaries 选择zip文件下载就可以了

openai chat GPT-4 Technical Report 技术报告论文

摘要 我们报告了 GPT-4 的开发&#xff0c;这是一个大规模、多模态的模型&#xff0c;可以接受图像和文本输入&#xff0c;并生成文本输出。虽然在许多现实场景中不如人类&#xff0c;但 GPT-4 在各种专业和学术基准测试中表现出与人类水平相当的性能&#xff0c;包括在模拟的…

代码编写规范

这里写目录标题 空格头文件位置换行缩进位置符号左右两边各加一个空格括号前面是否需要加空格分号前不加空格 缩进各种分级语句 大括号对于if、else以及for循环等其他语句大括号左括号的位置二级目录 变量名、函数名变量名函数名在类unix系统下编程 注释哪些地方需要注释函数内…

【数据结构】栈「介绍+完整代码+调试」

1.栈 1.1栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端 称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则。压…

潮乎新年盲盒H5版本可易支付对接

添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 潮乎新年盲盒H5版本可易支付对接 前端三十行和三十一行改成你域名百度网盘

毕设(二)——NB-IOT通信模块(nb卡通信测试)+gps定位

文章目录 一、关于接线2月1日记录2月4日记录 二、网络连接测试三、HTTP通信3.1 网络调试3.2 nb-lot的连接测试 一、关于接线 如果pico的供电能力不行&#xff0c;可能会直接用4.2V的锂电池对右下引脚进行供电 这个模块只支持nb卡&#xff0c;我哭死&#xff0c;20块钱&#xff…

第二件事 在Java 虚拟机 (JVM)跑一个程序

上篇文章写了 在 WINDOWS上 创建了一个 JVM&#xff0c; 好&#xff01; 现在在这个 Java 虚拟计算机系统上跑一个Java语言编写的小程序&#xff1b; 题目&#xff1a; 用Java语言 编写一个小程序 在Console界面 打印 整数 1-10 (回头了一下源程序&#xff0c;靠&#xff0c;应…

行人重识别综述

Deep Learning for Person Re-identification: A Survey and Outlook 论文地址https://arxiv.org/pdf/2001.04193 1. 摘要 we categorize it into the closed-world and open-world settings. closed-world&#xff1a;学术环境下 open-world &#xff1a;实际应用场景下 2…

AI专题:AI巨轮滚滚向前

今天分享的是电子系列深度研究报告&#xff1a;《AI专题&#xff1a;AI巨轮滚滚向前》。 &#xff08;报告出品方&#xff1a;方正证券&#xff09; 报告共计&#xff1a;65页 来源&#xff1a;人工智能学派 Gemini 1.5 Pro 性能显著增强&#xff0c;长上下文理解取得突破 …

SpringBoot自动注入源码分析

Spring Boot何时注入Autowired标注的属性&#xff1f; 是在Bean实例化后&#xff0c;填充Bean的时候注入Autowired标注的属性 如果注入类型的Bean存在多个&#xff0c;Spring Boot是如何处理的&#xff1f; 如果存在多个类型的Bean&#xff0c;会根据primary—>javax.ann…

我的NPI项目之Android USB 系列(一) - USB第一面

和USB应该是老朋友了&#xff0c;从2011年接触Android开发开始&#xff0c;就天天和USB打交道了。那时候还有不 对称扁头的usb/方口的usb&#xff0c;直到如今使用广泛的防反插USB3.0 type-C。 但是&#xff0c;一直有一个不是很清楚的问题萦绕在心头&#xff0c;那就是。先有…

天洑AIFEM软件将助力竞技机器人国际冠军战队再攀高峰

2023年底&#xff0c;烈鹏战队作为中国顶尖机器人队伍代表出征国际赛事Battle of Robots&#xff0c;经过与全球战队激烈竞争&#xff0c;取得国际赛场上5连胜的优秀战绩斩获国际冠军。 天洑智能结构仿真软件AIFEM与玄智科技的技术方案联合&#xff0c;基于烈鹏战队的冠军机器人…

基于shp数据制作3DTiles建筑白膜

经纬管网建模系统MagicPipe3D&#xff0c;本地离线参数化构建地下管网、建筑三维模型&#xff0c;输出标准3DTiles服务、Obj模型等格式&#xff0c;支持Cesium、Unreal、Unity、Osg等引擎加载进行三维可视化、语义查询、专题分析。欢迎下载试用&#xff1a;http://www.magic3d.…

P1824 进击的奶牛题解

题目 Farmer John 建造了一个有N&#xff08;2≤N≤105) 个隔间的牛棚&#xff0c;这些隔间分布在一条直线上&#xff0c;坐标是&#xff08;0≤​≤&#xff09;。 他的C&#xff08;2≤C≤N&#xff09;头牛不满于隔间的位置分布&#xff0c;它们为牛棚里其他的牛的存在而愤…