Linux信号(保存)

个人主页:Lei宝啊 

愿所有美好如期而遇


前言

Linux信号(产生)-CSDN博客,上一个章节我们详细介绍了信号是什么,为什么要有信号,怎样产生信号,以及信号产生的几个问题,这个章节我们将介绍信号的保存。

我们说,信号被发送给一个进程时不一定要立即处理,如果进程在处理临界区时,那么信号就会被保存在进程PCB中,怎么保存?使用位图,结合上个章节,我们说当操作系统通过中断向量表中的方法将键盘按下的数据读上来后进行判定,如果是普通字符,那么就写到键盘的缓冲区中,如果是控制命令,那么就解释成信号发送给进程,那么这句标红的话是什么意思?我们将图贴过来解释:

其实就是将2号信号写到task_struct中的pending位图中,因为没有0号信号,第一位就不使用。

解决上节的遗留问题:Core和Term区别,同时提出一个新问题。

这两个信号,我们分别测试一下。

Core和Term好像没什么区别,都终止了进程,SIGFPE信号仅仅只是在后面多加了core dumped,但core dumped是什么意思?

core dump:核心转储,将进程在内存中的核心数据(与调试有关)转储到磁盘上形成,也就是说,action动作为Core的信号,在进程收到这类信号时,会生成一个core文件,这个文件中包含着,进程为什么崩溃,在第几行崩溃,这个文件可以协助我们进行调试。

那么,另一个问题,下面这张图中的core dump是什么意思?

这个标志位的意思是,标志进程是否发生核心转储,在进程退出时,我们可以通过status变量来获取进程的状态,我们来获取一下两者的core dump标志,再看看Term和Core有什么区别:

#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>using namespace std;int main()
{int id = fork();if(id == 0){int a = 10;a/= 0;}int status;int rid = waitpid(id,&status,0);cout << "core dump: " <<((status >> 7) & 0x1) << endl; return 0;
}
#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>using namespace std;int main()
{int id = fork();if(id == 0){kill(getpid(),9);}int status;int rid = waitpid(id,&status,0);cout << "core dump: " <<((status >> 7) & 0x1) << endl; return 0;
}

在云服务器上,生成核心转储的功能默认是被关闭的,需要我们主动打开,至于为什么会默认关闭,我们后面点说。

现在我们来看看核心转储如何打开和关闭:

核心转储文件大小为0表示关闭。

使用命令ulimit -c 文件大小 开启核心转储功能。

现在,我们再来跑一下可执行程序,注意,我们仅仅只是打开了核心转储,其余多余动作都没有做。(core文件在ubantu5.15中被保存在/corefile下)

我们可以看到,Core动作的8号信号产生了core文件,同时core dump标志位被置1,而Term动作的9号信号没有产生core文件。

也就是说,core文件的产生需要这样的条件:首先动作为Core,再一个就是ulimit -c 文件大小,这个文件大小不为0。

接下来我们使用core文件协助我们进行调试:

小总结:

Term和Core的主要区别就在于core文件上,Core信号在核心转储功能打开的情况下,可以产生core文件来协助调试,得到报错信息以及位置,同时,对这个信号进行递达的进程会将core dump标志位设为1。

信号的保存

  • 实际执行信号的处理动作称为信号递达,而信号递达的方式有三种:默认,自定义,忽略。
  • 信号从产生到递达之间的状态称为信号未决(Pending),其实也就是信号的保存。
  • 进程可以选择阻塞某个信号。

我们仍然要提起,信号不是一定要立即处理的,所以有了信号的保存。

在内核中,信号的保存实际上是有三张表的,pending表:临时存储信号,block表:表示要阻塞哪些信号,函数指针数组表:存储各种信号处理方法的地址,我们看图:

  • Pending位图:bit位的位置表示信号编号,bit位的内容表示是否收到指定信号。
  • Block位图:     bit位的位置表示信号编号,bit位的内容表示是否阻塞指定信号。
  • handler表: 根据Pending位图比特位为1的编号,在表中索引处理方法地址,调用方法。

如果一个信号被阻塞,那么这个信号永远不会被递达,除非被解除阻塞,那么有人就会这样:我将信号全部阻塞,进程是不是就无法退出了?这个问题我们后面实践一下。

阻塞和忽略的区别:阻塞是在递达前,而忽略是递达的动作,是递达后,简单来说,就是被屏蔽和已读不回的区别。

阻塞一个信号,是需要我们进行设置的,handler表中的处理方法我们也可以通过signal系统调用进程更改,下面我们将对这三张表进行操作。

首先我们提出一个场景:

阻塞2号信号,并发送2号信号,获取Pending表。

先来看阻塞信号的系统调用

第一个参数how,意为如何阻塞一个信号,有三种宏来决定:

  • SIG_BLOCK,相当于向Block表中或上我们要新增的阻塞信号。
  • SIG_UNBLOCK,相当于解除某些信号的阻塞。
  • SIG_SETMASK,相当于直接使我们希望阻塞的信号集覆盖信号屏蔽字。

第二个参数,我们在栈上定义一个sigget_t类型的对象,然后通过和他配套的方法将我们想阻塞的信号设置进去,然后通过这个参数将他们设置进内核。

信号集操作函数:

#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); 

第三个参数,老的信号屏蔽字,我们可以通过这个参数带出来。 

获取Pending表的系统调用

接下来我们通过代码来理解上面这些:

#include <iostream>
#include <signal.h>
#include <unistd.h>using namespace std;void Print(sigset_t pending)
{cout << "pid: " << getpid() << " pending: ";for (int i = 31; i > 0; i--){if (sigismember(&pending, i))cout << "1";elsecout << "0";}cout << endl;
}void handler(int signo)
{cout << signo << "号信号被递达--";sigset_t pending;sigpending(&pending);Print(pending);
}int main()
{// 阻止2号信号使进程退出signal(2, handler);// 栈上我们想要阻塞的信号sigset_t block;sigemptyset(&block);sigaddset(&block, 2);// 设置进入内核sigprocmask(SIG_SETMASK, &block, nullptr);// 打印Pending表信息int cnt = 0;while (true){cnt++;sigset_t pending;sigpending(&pending);Print(pending);sleep(1);//解除对2号信号的屏蔽if(cnt == 20) sigprocmask(SIG_UNBLOCK,&pending,nullptr);}return 0;
}

那么有人就会这样搞:我让所有信号被屏蔽,那么是不是这个进程就退出不了了呢?我们来试试:

#include <iostream>
#include <signal.h>
#include <unistd.h>using namespace std;void Print(sigset_t pending)
{cout << "pid: " << getpid() << " pending: ";for (int i = 31; i > 0; i--){if (sigismember(&pending, i))cout << "1";elsecout << "0";}cout << endl;
}void handler(int signo)
{cout << signo << "号信号被递达--";sigset_t pending;sigpending(&pending);Print(pending);
}int main()
{// 阻止2号信号使进程退出signal(2, handler);// 栈上我们想要阻塞的信号sigset_t block;sigfillset(&block);// sigemptyset(&block);// sigaddset(&block, 2);// 设置进入内核sigprocmask(SIG_SETMASK, &block, nullptr);// 打印Pending表信息int cnt = 0;while (true){cnt++;sigset_t pending;sigpending(&pending);Print(pending);sleep(1);//解除对2号信号的屏蔽//if(cnt == 20) sigprocmask(SIG_UNBLOCK,&pending,nullptr);}return 0;
}

我们这里就不做演示了,直接给出结论:

9号,19号信号无法被屏蔽,18号信号会做特殊处理。

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

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

相关文章

嵌入式linux学习之arm开发板移植ssh

1.下载源码 &#xff08;1&#xff09;zlib 下载网址&#xff1a;http://www.zlib.net/fossils/ 教程中版本选择的是: zlib-1.2.11.tar.gz &#xff08;2&#xff09;openssl下载网址&#xff1a;https://www.openssl.org/source/mirror.html 教程中版本选择的是: openssl-1.1…

设计模式-迭代器模式(Iterator)

1. 概念 迭代器模式是一种行为型设计模式&#xff0c;它提供了一种统一的方式来访问集合对象中的元素。迭代器模式的核心思想是将遍历集合的责任封装到一个单独的对象中&#xff0c;这样可以避免暴露集合内部的表示方式。这种模式通常用于提供一种方法来访问一个容器对象中各个…

使用 Docker 部署 Draw.io 在线流程图系统

1&#xff09;介绍 Draw.io GitHub&#xff1a;https://github.com/jgraph/drawio Draw.io 是一款开源的绘制流程图的工具&#xff0c;拥有大量免费素材和模板。程序本身支持中文在内的多国语言&#xff0c;创建的文档可以导出到多种网盘或本地。无论是创建流程图、组织结构图…

如何帮助中小企业建立数字化的能力?

中小企业建立数字化的能力&#xff0c;可以从以下几个方面着手&#xff1a; 1、开展数字化评估&#xff1a;中小企业首先需要对自己的数字化基础水平和企业经营管理现状进行评估&#xff0c;这包括了解企业在数字化方面的现有能力和需求&#xff0c;以及内外部转型资源的可用性…

[创业之路-106] :经济学十大陷阱与核心思想:系统论、社会进化论、周期论、阴阳互转论

目录 前言&#xff1a; 一、流动性陷阱。 二、中等收入陷阱。 三、修昔底德陷阱。 四、塔西佗陷阱。 五、金德尔伯格陷阱。 六、卢梭陷阱。 七、拉美陷阱。 八、阿喀琉斯之踵。 九、布拉德伯里悖论。 十、李约瑟之谜 结论&#xff1a;上述陷阱的…

AI智能客服机器人原来这么好用,企业再不使用就落伍了!

随着人工智能技术的不断成熟&#xff0c;AI智能客服机器人已经变得越来越智能&#xff0c;它们正逐渐成为企业提供客户服务的强大助手。企业若不开始部署这种高效的技术&#xff0c;可能会在竞争中失去先机。下面&#xff0c;让我们来看看AI智能客服机器人为何如此好用&#xf…

vue +antvX6 根据节点与线,动态设置节点坐标生成流程图

需求 vue2 + antvX6完成流程图,但只有节点与线,没有节点的坐标,需要根据节点的顺序显示流程图。 需求: 1.根据数据动态生成对应的节点与线; 2.节点不能重叠; 3.节点与线可拖拽; 4.因为线存在重叠可能,所有鼠标移入时线必须高亮显示(红色),鼠标移出复原; 5.要求有…

Spring-基于xml自动装配

版本 Spring Framework 6.0.9​ 1. 定义 Spring IoC容器在无需显式定义每个依赖关系的情况下&#xff0c;根据指定的策略&#xff0c;自动为指定的bean中所依赖的类类型或接口类型属性赋值。 2. 关键配置元素 BeanDefinitionParserDelegate类定义了autowire属性的属性值&…

绿联 安装transmission

绿联 安装transmission及中文UI 1、镜像 linuxserver/transmission:latest 2、安装 2.1、创建容器 按需配置权重。 2.2、基础设置 2.3、网络 桥接即可。 注&#xff1a;如果使用IPV6&#xff0c;请选择"host"模式。 注&#xff1a;如果使用IPV6&#xff0c;请选…

Git禁止松散对象loose objects弹窗

打开仓库时&#xff0c;弹窗如图 This repository currently has approximately XXXX loose objects.解决办法&#xff1a;见How to skip “Loose Object” popup when running ‘git gui’ Git v1.7.9 或以上版本&#xff0c;执行git config --global gui.gcwarning false

【计算机毕业设计】面向学生成绩分析系统产品功能介绍——后附源码

&#x1f389;**欢迎来到琛哥的技术世界&#xff01;**&#x1f389; &#x1f4d8; 博主小档案&#xff1a; 琛哥&#xff0c;一名来自世界500强的资深程序猿&#xff0c;毕业于国内知名985高校。 &#x1f527; 技术专长&#xff1a; 琛哥在深度学习任务中展现出卓越的能力&a…

NIO之ByteBuffer

NIO中的ByteBuffer是缓冲区&#xff0c;其中有几个比较重要的属性capacity&#xff0c;position和limit。 capacity&#xff1a; 其中&#xff0c;capacity是缓冲区的容量大小&#xff0c;在分配内存空间后不会改变。 limit&#xff1a; limit是限制位置&#xff0c;在读写模…

前端crypto-js, 文件加密,判断相同文件、图片(MD5,SHA256)

文章目录 前情提要应用场景实战解析最后前情提要 大家好,今天我们来接触一个库crypto-js 没错,上面是有道翻译的截图,为了我们得到的信息更权威,这个库是用来加密的,但介绍是说,已经停止维护,但并不影响我们在前端项目中的使用,所以学学也没有坏处 应用场景 判断图片…

亿发:新修订器械GSP重大变化,医疗器械GSP软件助力适应科学监管

随着医疗器械行业的快速发展和监管要求的提升&#xff0c;国家药监局近期发布了新修订的医疗器械GSP&#xff08;Good Storage Practice&#xff09;规范&#xff0c;旨在加强医疗器械流通环节的质量管理和监督&#xff0c;确保医疗器械的安全、有效和可追溯。这一重大变化为医…

万益蓝Wonderlab益生菌:吃雪糕的自由,我终于找回来了!

虽然现在不是夏天&#xff0c;但是我必须要来说一下&#xff01;我不仅在夏天可以吃雪糕&#xff01;冬天吃也完全没有问题&#xff01; 夏天&#xff0c;对于很多人来说&#xff0c;是雪糕、冷饮和冰镇西瓜的代名词。但对于我&#xff0c;这简直就是个“禁区”。每次看着别人…

SpringBoot项目启动的时候直接退出了?

SpringBoot项目启动的时候直接退出了&#xff1f; 如下图&#xff1a; 在启动SpringBoot项目的时候仅仅用了1.209s&#xff0c;然后直接退出了&#xff0c;也没有出现启动的项目对应的服务器端口号&#xff1f;为什么会这样呢&#xff1f;因为既然有服务器端口号 那么肯定会有…

【php开发工程师系统性教学】——Laravel框架(验证码)的配置和使用的保姆式教程

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

MySQL的事务相关的语句的使用

MySQL的事务相关的语句的使用 事务是数据库管理系统执行过程中的一个程序单位&#xff0c;由一个或多个数据库操作组成。MySQL作为一款流行的关系型数据库管理系统&#xff0c;支持事务处理&#xff0c;允许用户定义一系列的操作&#xff0c;这些操作要么完全执行&#xff0c;…

数仓建模—数仓架构发展史

数仓建模—数仓架构发展史 时代的变迁,生死的轮回,历史长河滔滔,没有什么是永恒的,只有变化才是不变的,技术亦是如此,当你选择互联网的那一刻,你就相当于乘坐了一个滚滚向前的时代列车,开往未知的方向,不论什么样的技术架构只有放在当前的时代背景下,才是有意义的,…

MySQl-8.3.0版本安装下载教程(超详细保姆级教程)

第一步&#xff0c;去百度找到MySQl官网 第二步,找到DOWNLOAD&#xff08;下载&#xff09; 第三步 第四步 第五步 第六步.选择倒数第2个 第七步 第八步然后根据步骤安装就好了