【Linux】信号知识三把斧——信号的产生、保存和处理

目录​​​​​​​

1、关于信号的前置知识

1.1.什么是信号?

1.2.为什么要学习信号?

1.3.如何学习信号?

1.4.一些常见的信号

1.5.信号的处理方式

1.6.为什么每一个进程都可以系统调用?

2.信号的产生

2.1.kill命令产生信号

2.2.键盘产生信号

CTRL+c和CTRL+\的区别

2.3.调用系统函数向进程发信号

2.4.软件条件产生信号

2.5.异常产生信号(硬件异常)

2.6.信号产生的小总结

3.信号的保存

3.1三张表基础

阻塞vs忽略:

3.2三张表匹配的操作和系统调用

3.3.Core和Term

如何打开Linux的core功能呢?

为什么要用核心转储功能呢?

4.信号的处理

4.1.信号什么时候被处理的?

4.2.信号是如何被处理的?

4.3.volatile

1、关于信号的前置知识

1.1.什么是信号?

Linux系统提供的让用户(进程)给其他进程发送异步信息的一种方式。(注意信号和信号量这两者没有任何关系!)

举个例子:

用户输入命令,在Shell下启动一个前台进程。用户按下 Ctrl-C ,这个键盘输入产生一个硬件中断,被OS获取,解释成信号,发送给目标前台进程前台进程因为收到信号,进而引起进程退出~

进程就是你,操作系统就是快递员,信号就是快递

1.2.为什么要学习信号?

我们平时在处理进程的时候,对于停止、删除进程等操作,系统要求进程要有随时响应外部信号的能力,随后做出反应

1.3.如何学习信号?

根据进程对于整体信号的操作过程进行学习。

  1. 信号的产生(kill命令和键盘产生信号)
  2. 信号的保存
  3. 信号的处理

1.4.一些常见的信号

用kill -l命令可以察看系统定义的信号列表

数组和名字都可以标识一个信号,名字其实就是宏,注意没有信号0,没有信号32和33

1.5.信号的处理方式

  • 信号自己的默认动作
  • 自定义处理信号,捕捉信号
  • 忽略信号,忽略也代表处理过信号了

所以我们自己是可以更改对信号的处理方式。

1.6.为什么每一个进程都可以系统调用?

写时拷贝的时候拷贝的全部都是用户空间,不会拷贝内核空间

每一个进程都有自己的地址空间,多个进程就会有多个地址空间,但是内核空间只有一份。所以任何一个进程都可以系统调用

2.信号的产生

2.1.kill命令产生信号

当我们输入kill命令去给进程发送信号的时候,本质是OS进行操作的。

2.2.键盘产生信号

键盘如何产生信号呢?

常见的有CTRL+c,代表中断这个程序;CTRL+ \发送SIGQUIT信号给当前进程,导致该进程退出并生成core转储文件

CTRL+c和CTRL+\的区别

CTRL+\与Ctrl+C不同,后者只是发送SIGINT信号给当前正在运行的进程,导致进程被终止。Ctrl+\会生成core文件,这个文件包含了进程在退出时的内存映像,可以用于调试。如果进程成功生成core文件,那么可以使用调试工具来分析这个文件,以了解进程崩溃时的状态,这对于排查问题非常有帮助‌。

2.3.调用系统函数向进程发信号

kill命令是调用kill函数实现的。kill函数可以给一个指定的进程发送指定的信号。raise函数可以给当前进程发送指定的信号(自己给自己发信号)。

  • kill函数对任意进程发送任意的信号
  • raise函数对自己发送任意信号

#include <signal.h>
int kill(pid_t pid, int signo);
int raise(int signo);
这两个函数都是成功返回0,错误返回-1

abort函数使当前进程接收到信号而异常终止

#include <stdlib.h>
void abort(void);
就像exit函数一样,abort函数总是会成功的,所以没有返回值。

2.4.软件条件产生信号

alarm函数 和SIGALRM信号就是由软件条件产生信号的代表

#include <unistd.h>
unsigned int alarm(unsigned int seconds);
调用alarm函数可以设定一个闹钟,也就是告诉内核在seconds秒之后给当前进程发SIGALRM信号, 该信号的默认处理动
作是终止当前进程。

这个函数的返回值是0或者是以前设定的闹钟时间还余下的秒数。如果参数seconds值为0,表示取消以前设定的闹钟,函数的返回值仍然是以前设定的闹钟时间还余下的秒数

2.5.异常产生信号(硬件异常)

  • 代码除零产生异常
  • 野指针异常

硬件异常被硬件以某种方式被硬件检测到并通知内核,然后内核向当前进程发送适当的信号。

例如当前进程执行了除以0的指令,CPU的运算单元会产生异常,内核将这个异常解释 为SIGFPE信号发送给进程。

再比如当前进程访问了非法内存地址,MMU会产生异常,内核将这个异常解释为SIGSEGV信号发送给进程。

注意寄存器只有一个,但是寄存器的数据可以有很多,我们把寄存器中的数据叫做:上下文数据!!!

2.6.信号产生的小总结

当信号产生的时候,如果进程在处理更加重要的事情,我们就暂时不能处理到来的信号,我们必须暂时要将到来的信号进行临时保存。

那么问题来了,我们将这些信号保存在哪里呢?——进程的PCB中

所以只有OS才有资格写入信号,如果用户也想写入信号,就必须使用OS提供的系统调用。因此,无论信号产生的方式有多少种,最终都是OS亲自动手将信号写入进程的!!!

3.信号的保存

3.1三张表基础

理论上来说我们用3张表就可以保存信号

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

阻塞vs忽略:

忽略是一种信号递达的方式。阻塞仅仅是不让指定信号进程递达

  • pending表比特位的位置,表示信号编号,比特位的内容,表示是否收到指定信号
  • block表的比特位的位置,表示信号编号,比特位的内容,表示是否阻塞该信号

下面这三张表需要我们横着读,最后一个handler表示对信号的处理方法

这三张表分别表示信号是否阻塞,信号是否接受到,信号的处理动作

所以我们看这张表的时候,不是竖着看,而是横着看每一个信号

3.2三张表匹配的操作和系统调用

block表对应的是sigprocmask函数

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

#include <signal.h>
int sigprocmask(int how, const sigset_t *set, sigset_t *oset);
返回值:若成功则为0,若出错则为-1

如果oset是非空指针,则读取进程的当前信号屏蔽字通过oset参数传出。如果set是非空指针,则 更改进程的信号屏蔽字,参数how指示如何更改。如果oset和set都是非空指针,则先将原来的信号 屏蔽字备份到oset里,然后根据set和how参数更改信号屏蔽字。假设当前的信号屏蔽字为mask,下表说明了how参数的可选值。

pending表对应的是sigpending函数

#include <signal.h>
sigpending
读取当前进程的未决信号集,通过set参数传出。调用成功则返回0,出错则返回-1。

handler函数对应的是signal函数。

可以对指定的信号进行用户指定的信号处理。更改信号的处理方式。

下面是利用这几个函数进行编码,小试牛刀。 

3.3.Core和Term

大多数信号的默认响应行为都是Core或者Term;

这两种信号都表示终止进程

区别:

  • Term就是普通的终止进程,之后没有其他动作。
  • Core不仅会终止进程,还会生成一个核心转储文件

为什么默认关闭核心转储功能?防止未知的core dump 一直在进行,导致服务器磁盘被打满,所以默认core是关闭的。

如何打开Linux的core功能呢?

使用ulimit -a查看当前资源限制的设定 ;

其中,第一行显示core文件的大小为0,即表示核心转储是被关闭的

通过ulimit -c size 命令来设置Core文件的大小(同时也是打开了核心转储

为什么要用核心转储功能呢?

想通过core定位到进程为什么退出,以及执行到哪行代码退出的

核心转储功能是什么?

将进程在内存中的核心数据(与调试有关)转储到磁盘中形成。

有什么用呢?

协助我们进行调试!

4.信号的处理

4.1.信号什么时候被处理的?

合适的时候,什么是合适的时候呢?进程从内核态(操作系统的状态,权限级别高),切换到用户态(你自己的状态)的时候,信号会被检测并处理

在信号处理的过程(捕捉)中,一共会有4次的状态切换(内核和用户态)

4.2.信号是如何被处理的?

我们使用系统调用或者访问系统数据,其实还是在进程的地址空间内进行切换的

进程无论如何被切换,总能找到OS,我们访问OS,本质就是通过我们的进程的地址空间进行访问

4.3.volatile

volatile 作用:保持内存的可见性,告知编译器,被该关键字修饰的变量,不允许被优化,对该变量的任何操作,都必须在真实的内存中进行操作

 

编译器正常处理是将flag的值从内存读取到CPU中进行处理

当前编译器做了一个优化,因为系统认为flag的值定义之后就没有改变,因此直接将内存里flag的值直接放在了CPU 的寄存器中,因此后面代码改变flag值的时候,是在内存当中改变的,CPU中的值不会改变,而程序读取数据是从CPU读取的,因此就会造成偏差,这时候就需要我们的volatile去修饰这个变量,默认从内存中读取!​​​​​​​

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

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

相关文章

OpenCV视频I/O(7)视频采集类VideoCapture之初始化视频捕获设备或打开一个视频文件函数open()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 为视频捕获打开一个视频文件、捕获设备或 IP 视频流。 这是一个重载成员函数&#xff0c;提供给用户方便使用。它与上述函数的不同之处仅在于它所…

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-09-28

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-09-28 目录 文章目录 计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-09-28目录前言1. Cognitive phantoms in LLMs through the lens of latent variables摘要研究背景问题与挑战创新点算法模型实验效果…

《Linux从小白到高手》理论篇补充:深入理解Linux中的输入输出及重定向

List item 今天继续宅家&#xff0c;闲来无事接着写。本篇是《Linux从小白到高手》理论篇补充篇。本篇深入介绍Linux中的输入输出及重定向。 输入和输出&#xff08;I/O&#xff09;是操作系统与用户、程序以及硬件设备之间交互的基本方式。Linux有很多输入输出操作&#xff0c…

【C++】二叉搜索树+变身 = AVL树

&#x1f680;个人主页&#xff1a;小羊 &#x1f680;所属专栏&#xff1a;C 很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~ 目录 前言一、AVL树二、AVL树的实现2.1 平衡因子2.2 旋转处理2.2.1 左单旋&#xff1a;插入新节点后单纯的右边高2.2.2 …

html5 + css3(上)

目录 HTML初识基础认知web标准vscode的简介和使用注释 HTML标签学习排版标签标题和段落换行和水平线标签 文本格式化标签媒体标签图片标签图片-基本使用图片-属性 路径绝对路径相对路径 音频标签视频标签链接标签 HTML基础列表标签列表-无序和有序列表-自定义 表格标签表格-使用…

Golang学习路线

以下是一条学习Golang&#xff08;Go语言&#xff09;的路线&#xff1a; 一、基础入门 1. 环境搭建 安装Go编译器&#xff0c;在官网&#xff08;https://golang.org/dl/&#xff09;下载适合操作系统的安装包并配置好环境变量。 2. 语法学习学习变量、数据类型&#xff08…

【包教包会】2D图片实现3D透视效果(支持3.x、支持原生、可合批)

将去年写的SpriteFlipper从2.x升级到3.x。 如果需要2.x版本或需要了解算法思路&#xff0c;请移步&#xff1a;https://blog.csdn.net/weixin_42714632/article/details/136745051 优化功能&#xff1a;可同时绕X轴和Y轴旋转&#xff0c;两者效果会叠加。 完美适配Web、原生…

数据结构与算法篇(图)(持续更新迭代)

目录 一、引言 二、基本概念 三、图的定义 四、图的基本概念和术语 1. 有向图 2. 无向图 3. 简单图 4. 多重图 5. 完全图&#xff08;也称简单完全图&#xff09; 6. 子图 7. 连通、连通图和连通分量 8. 强连通图、强连通分量 9. 生成树、生成森林 10. 顶点的度、…

深入理解 JavaScript 中的 void`运算符和 yield*表达式

深入理解 JavaScript 中的 void 运算符和 yield* 表达式 在 JavaScript 中&#xff0c;void 运算符和 yield* 表达式是两个功能独特但常被忽视的运算符。本文将详细介绍它们的用法和应用场景&#xff0c;帮助您更好地理解和运用这两个运算符。 目录 void 运算符概述void 运算…

Django学习笔记四:urls配置详解

Django是一个高级的Python Web框架&#xff0c;它鼓励快速开发和干净、实用的设计。URL配置是Django框架中非常重要的一部分&#xff0c;它定义了URL模式与视图函数之间的映射关系。以下是Django URL配置的详解&#xff1a; URL配置文件 通常&#xff0c;URL配置位于Django项…

Spring Boot 配置全流程 总结

1. 简介 Springboot可以简化SSM的配置,提高开发效率。 2. 代码 在pom.xml中添加: <parent><!-- 包含SSM常用依赖项 --><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><versi…

【达梦数据库】尽可能 disql 的使用效果与异构数据库一致

文章目录 前言disql 效果优化参数设置参数说明 mysql参数设置参数说明 db2参数设置参数说明 待补充 前言 让达梦的disql 使用起来更跟手&#xff0c;与其他优质数据库的命令行工具通过配置参数的方式尽可能一致&#xff0c;提高使用体验&#xff0c;长期整理中~~~ 测试版本&…

使用WPF实现一个快速切换JDK版本的客户端工具

发现网上一键切换JDK环境的方法都是在mac或Linux下的&#xff0c;本人主力电脑是Windows&#xff0c;于是看了一下WPF的文档&#xff0c;自己开发了一个客户端。 直接上代码吧&#xff1a; using JavaSwitch.Properties; using Newtonsoft.Json; using System; using System.…

【C++11】新特性

前言&#xff1a; C11 是C编程语言的一个重要版本&#xff0c;于2011年发布。它带来了数量可观的变化&#xff0c;包含约 140 个新特性&#xff0c;以及对 C03 标准中约600个缺陷的修正&#xff0c;更像是从 C98/03 中孕育出的新语言 列表初始化 C11 中的列表初始化&#xff0…

做副业赚钱时如何保持良好的心态?

在当今这个多元化的时代&#xff0c;越来越多的人选择开展副业来增加收入、拓展技能和实现自我价值。然而&#xff0c;副业之路并非总是一帆风顺&#xff0c;其间可能会遇到各种挑战和困难。在这个过程中&#xff0c;保持良好的心态至关重要&#xff0c;它不仅能帮助我们坚持下…

P05_盛最多水的容器

一、题目 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c; 第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明&#xff1a;你不能倾斜…

爬虫案例——爬取情话网数据

需求&#xff1a; 1.爬取情话网站中表白里面的所有句子&#xff08;表白词_表白的话_表白句子情话大全_情话网&#xff09; 2.利用XPath来进行解析 3.使用面向对象形发请求——创建一个类 4.将爬取下来的数据保存在数据库中 写出对应解析语法 //div[class"box labelbo…

vite学习教程03、vite+vue2打包配置

文章目录 前言一、修改vite.config.js二、配置文件资源/路径提示三、测试打包参考文章资料获取 前言 博主介绍&#xff1a;✌目前全网粉丝3W&#xff0c;csdn博客专家、Java领域优质创作者&#xff0c;博客之星、阿里云平台优质作者、专注于Java后端技术领域。 涵盖技术内容&…

云手机可以解决TikTok运营的哪些问题?

随着社交媒体的飞速发展&#xff0c;TikTok迅速崛起&#xff0c;成为个人和企业进行品牌宣传和内容创作的首选平台。然而&#xff0c;在运营TikTok账号的过程中&#xff0c;不少用户会遇到各种问题。本文将详细阐述云手机如何帮助解决这些问题。 1. 多账号管理的高效便捷 通过云…

外包功能测试干了4年,技术退步太明显了。。。。。​

先说一下自己的情况&#xff0c;本科生&#xff0c;18年通过校招进入武汉某软件公司&#xff0c;干了差不多4年的功能测试&#xff0c;今年中秋&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测…