linux:信号深入理解
文章目录
- 1.信号的概念
- 1.1基本概念
- 1.2信号的处理基本概念
- 1.3信号的发送与保存基本概念
- 2.信号的产生
- 2.1信号产生的五种方式
- 2.2信号遗留问题(core,temp等)
- 3.信号的保存
- 3.1 信号阻塞
- 3.2 信号特有类型 sigset_t
- 3.3 信号集操作函数
- 3.4 信号集操作函数的使用
- 4.信号的处理
- 4.1 信号的捕捉
- 4.2 深入理解地址空间
- 4.3 如何理解系统调用
- 4.4 sigaction对信号捕捉
- 5.可重入函数
- 6.编译器的优化及volatile关键字
- 7.SIGCHLD信号(子进程退出发的信号)
1.信号的概念
1.1基本概念
所谓同步和异步就是:
比如我正在上课,我让一个学生去帮我拿快递,然后我停下等那个学生回来再继续讲,即同步。
如果学生去拿快递,我不管他,我接着讲就是异步!
1-31号为普通信号!
34-64号实时信号!
1.2信号的处理基本概念
信号的处理大致分为三种:
a.默认动作
b.忽略动作
c.自定义处理—信号的捕捉
core,temp都是终止,在本篇文章的后面会有更详细的介绍!
1.3信号的发送与保存基本概念
2.信号的产生
2.1信号产生的五种方式
信号产生的三种主要方式和两种不常用接口:
如果把所有信号都捕捉,换成自定义动作那么怎么办?
答:操作系统有些信号是不允许自定义捕捉的,比如9号信号killed。如果所有信号都能被捕捉那不乱套了!!!而且信号的发送者只有一个,那就是操作系统发的,通过位图来执行!
下面还有两种信号产生的方式:
4.软件条件:
5.异常:
我们都知道进程发生异常了就会崩溃,然后就会退出。
这便是异常发送信号!
那么崩溃了为啥会退出?因为异常的默认动作是终止进程!
那么可以不退出嘛?可以的,我们可以自定义捕捉异常!但是不推荐这么做!
2.2信号遗留问题(core,temp等)
我们用一个多进程的例子再来看看标志位:
3.信号的保存
3.1 信号阻塞
3.2 信号特有类型 sigset_t
从上图来看,每个信号只有一个bit的未决标志,非0即1,不记录该信号产生了多少次,阻塞标志也是这样表示的。因此,未决和阻塞标志可以用相同的数据类型sigset_t来存储,sigset_t称为信号集,这个类型可以表示每个信号的“有效”或“无效”状态,在阻塞信号集中“有效”和“无效”的含义是该信号是否被阻塞,而在未决信号集中“有效”和“无效”的含义是该信号是否处于未决状态。
阻塞信号集也叫做当前进程的信号屏蔽字(Signal Mask),这里的“屏蔽”应该理解为阻塞而不是忽略。
3.3 信号集操作函数
#include <signal.h>int sigemptyset(sigset_t *set); 把sigset_t 这个位图全部清空int sigfillset(sigset_t *set); 把整个位图全部置1int sigaddset (sigset_t *set, int signo); 把一个特定的信号signo设置到这个集合里(置1)int sigdelset(sigset_t *set, int signo); 把一个特定的信号signo在这个集合里清除(置0)int sigismember(const sigset_t *set, int signo); 判断一个信号是否在集合中
以及两个系统调用函数:
3.4 信号集操作函数的使用
#include <iostream>
#include <unistd.h>
#include <cstdio>
#include <sys/types.h>
#include <sys/wait.h>void PrintPending(sigset_t &pending)
{std::cout << "curr process[" << getpid() << "]pending: ";for (int signo = 31; signo >= 1; signo--){if (sigismember(&pending, signo)){std::cout << 1;}else{std::cout << 0;}}std::cout << "\n";
}void handler(int signo)
{std::cout << signo << " 号信号被递达!!!" << std::endl;std::cout << "-------------------------------" << std::endl;sigset_t pending;sigpending(&pending);PrintPending(pending);这里正在处理handler方法的时候,把pending再获取一次如果这时候打印出来的pending信号为1,就说明只能把handler方法处理完才能清空如果这时候打印出来的pending信号为全0,就说明在进入handler方法之前就把1清零了std::cout << "-------------------------------" << std::endl;
}int main()
{// 0. 捕捉2号信号signal(2, handler); // 自定义捕捉2号信号默认操作是退出,所以我们要自定义捕捉,否则推出了就看不到后面的现象了。// 1. 屏蔽2号信号sigset_t block_set, old_set;sigemptyset(&block_set);sigemptyset(&old_set);sigaddset(&block_set, SIGINT); // 我们有没有修改当前进行的内核block表呢???1 0// 1.1 设置进入进程的Block表中sigprocmask(SIG_BLOCK, &block_set, &old_set); // 真正的修改当前进行的内核block表,完成了对2号信号的屏蔽!int cnt = 15;while (true){// 2. 获取当前进程的pending信号集sigset_t pending;sigpending(&pending);// 3. 打印pending信号集PrintPending(pending);cnt--;// 4. 解除对2号信号的屏蔽if (cnt == 0){std::cout << "解除对2号信号的屏蔽!!!" << std::endl;sigprocmask(SIG_SETMASK, &old_set, &block_set);}sleep(1);}
}
4.信号的处理
4.1 信号的捕捉
4.2 深入理解地址空间
4.3 如何理解系统调用
4.4 sigaction对信号捕捉
5.可重入函数
main函数调用insert函数向一个链表head中插入节点node1,插入操作分为两步,刚做完第一步的时候,因为硬件中断使进程切换到内核,再次回用户态之前检查到有信号待处理,于是切换到sighandler函数,sighandler也调用insert函数向同一个链表head中插入节node2,插入操作的两步都做完之后从sighandler返回内核态,再次回到用户态就从main函数调用的insert函数中继续往下执行,先前做第一步之后被打断,现在继续做完第二步。结是,main函数和sighandler先后向链表中插入两个节点,而最后只有一个节点真正插入链表中了!
像上例这样,insert函数被不同的控制流程调用,有可能在第一次调用还没返回时就再次进入该函数,这称为重入,insert函数访问一个全局链表,有可能因为重入而造成错乱,像这样的函数称为不可重入函数。
6.编译器的优化及volatile关键字
7.SIGCHLD信号(子进程退出发的信号)
要想不产生僵尸进程还有另外一种办法:父进程调 用sigaction将SIGCHLD的处理动作置为SIG_IGN,这样fork出来的子进程在终止时会自动清理掉,不会产生僵尸进程,也不会通知父进程。
相关文章:

linux:信号深入理解
文章目录 1.信号的概念1.1基本概念1.2信号的处理基本概念1.3信号的发送与保存基本概念 2.信号的产生2.1信号产生的五种方式2.2信号遗留问题(core,temp等) 3.信号的保存3.1 信号阻塞3.2 信号特有类型 sigset_t3.3 信号集操作函数3.4 信号集操作函数的使用 4.信号的处理4.1 信号的…...

Android系统的/etc/mkshrc文件
/etc/mkshrc 文件是用于配置 mksh(MirBSD Korn Shell)环境的启动脚本。mksh 是 Android 默认使用的 shell,在 shell 启动时会读取并执行这个文件中的配置。以下是关于 /etc/mkshrc 文件的详细信息及其用途。 /etc/mkshrc 文件的作用 环境配…...

LeetCode199二叉树的右视图
题目描述 给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。 解析 这一题的关键其实就是找到怎么去得到当前是哪一层级,可以利用队列对二叉树进行层次遍历,但…...

JavaScript 基础
一 JavaScript 的书写形式 1.1 行内式 <input type"button" value"点我一下" onclick"alert(hello akai);" > 注意,JS 中的字符串常量可以用单引号表示,也可以使用双引号表示.HTML 中推荐使用双引号,JS 中推荐使用单引号(使用双引号容易…...

DOS学习-目录与文件应用操作经典案例-type
新书上架~👇全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一.前言 二.使用 三.案例 1. 查看文本文件内容 2. 同时查看多个文本文件内容 3. 合并文…...

QT教程-一,初识QT
目录 一,QT是什么?能够使用它做什么? 二,Qt 能够使用的语言 三,Qt主要用于什么领域? 四,Qt开发的软件 一,QT是什么?能够使用它做什么? Qt是一个跨平台的 C 开发库,主…...

SpringBoot搭建Eureka注册中心
系列文章目录 文章目录 系列文章目录前言前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 1、Spring-Cloud Euraka介绍 Spring-Cloud Euraka是Spring Cloud集合中一…...

day 38 435.无重叠区间 763.划分字母区间 56. 合并区间 738.单调递增的数字 968.监控二叉树
435.无重叠区间 思路 为了使区间尽可能的重叠所以排序来使区间尽量的重叠,使用左边界排序来统计重叠区间的个数与452. 用最少数量的箭引爆气球恰好相反。 代码 class Solution {public int eraseOverlapIntervals(int[][] intervals) {Arrays.sort(intervals,(a,…...

ssm/springoot养老院问诊服务预约系统_96316老年人服务系统
2.管理员: (1)登入注册页面:管理员进行操作时需要是已注册登入的 (2)权限管理:管理员登入后可以运用权限进行相应的操作管理。 (3)用户管理:对用户进行删除、…...

WordPress插件优化对提升性能有多大影响?
WordPress插件优化对提升性能的影响可以是非常显著的。插件是WordPress平台的一个重要组成部分,它们可以增强网站的功能和定制性。然而,如果插件没有经过优化,它们可能会成为网站性能的瓶颈。 通过优化插件,可以减少对服务器资源…...

Servlet的response对象
目录 HTTP响应报文协议 reponse继承体系 reponse的方法 响应行 public void setStatus(int sc) 响应头 public void setHeader(String name, String value) 响应体 public java.io.PrintWriter getWriter() public ServletOutputStream getOutputStream() 请求重定…...

Unity射击游戏开发教程:(20)增加护盾强度
在本文中,我们将增强护盾,使其在受到超过 1 次攻击后才会被禁用。 Player 脚本具有 Shield PowerUp 方法,我们需要调整盾牌在被摧毁之前可以承受的数量,因此我们将声明一个 int 变量来设置盾牌可以承受的击中数量。...

初识C语言——第二十八天
代码练习1: 用函数的方式实现9*9乘法表 void print_table(int n) {int i 0;int j 0;for (i 1; i< n; i){for (j 1; j< i; j){printf("%d*%d%-3d ", i, j, i * j);}printf("\n");}}int main() {int n 0;scanf("%d", &a…...

Android NDK系列(三)输入事件分发到Native层的流程
在Android NDK系列(一)手动搭建Native Project 创建的Native工程中,是可以接收输入事件的,只需在android_main中注册输入事件的处理函数,当触摸屏幕后,handleInputEvent函数便会调用,代码如下。 static int32_t handleInputEvent(struct android_app* app, AInputEvent…...

Kafka之【生产消息】
消息(Record) 在kafka中传递的数据我们称之为消息(message)或记录(record),所以Kafka发送数据前,需要将待发送的数据封装为指定的数据模型: 相关属性必须在构建数据模型时指定,其中…...

asp.net core接入prometheus
安装prometheus和Grafana 参考之前的文章->安装prometheus和Grafana教程 源代码 dotnet源代码 新建.net core7 web项目 修改Program.cs using Prometheus;namespace PrometheusStu01;public class Program {public static void Main(string[] args){var builder We…...

C++ 变量类型与转换
C 变量类型与转换 文章目录 C 变量类型与转换变量int_tsize_t与ssize_tpid_ttime_t typenametypeid关键字类型转换编译期类型转换std::static_cast注意事项运行时类型转换std::dynamic_cast 变量 int_t 它是通过typedef定义的,而不是一种新的数据类型。 - int8_t…...

【杂七杂八】Huawei Gt runner手表系统降级
文章目录 Step1:下载安装修改版华为运动与健康Step2:在APP里进行配置Step3:更新固件(时间会很长) 目前在使用用鸿蒙4 111版本的手表系统,但是感觉睡眠检测和运动心率检测一言难尽,于是想到是否能回退到以前的版本&…...

FMEA做不出来的原因究竟是什么?——FMEA软件
免费试用FMEA软件-免费版-SunFMEA FMEA(Failure Mode and Effects Analysis)即故障模式与影响分析,是一种旨在识别并预防潜在问题的方法。然而,尽管其重要性被广泛认知,但在实际应用中,却常常遇到FMEA难以…...

pandas ExcelWriter写excel报错openpyxl.utils.exceptions.IllegalCharacterError
一直使用pandas写excel,本次写的数据有大字段,每次写到该字段就报错,代码如下: with pd.ExcelWriter(r".\提数_20240523\tq_type3_doc.xlsx", engineopenpyxl) as writer: df.to_excel(writer,indexFalse, sheet_namesh…...

Golang创建文件夹
方法 package zdpgo_fileimport ("os" )// AddDir 创建文件夹 func AddDir(dir string) error {if !IsExist(dir) {return os.MkdirAll(dir, os.ModePerm)}return nil }测试 package zdpgo_fileimport "testing"func TestAddDir(t *testing.T) {data : […...

头歌OpenGauss数据库-I.复杂查询第5关:至少学了某位学生(Oliver)所学的全部课程的学生
本关任务:根据提供的表和数据,查询至少学了Oliver同学所学的全部课程的其他同学的信息(学号s_id,姓名`s_name)。 student表数据: s_ids_names_sex01Mia女02Riley男03Aria女04Lucas女05Oliver男06Caden男07Lily女08Jacob男course表数据: c_idc_namet_id01Chinese0202Math…...

【数据结构】哈夫曼树和哈夫曼编码
一、哈夫曼树 1.1 哈夫曼树的概念 给定一个序列,将序列中的所有元素作为叶子节点构建一棵二叉树,并使这棵树的带权路径长度最小,那么我们就得到了一棵哈夫曼树(又称最优二叉树) 接下来是名词解释: 权&a…...

深入探索微软Edge:领略新一代浏览器的无限可能
深入探索微软Edge:领略新一代浏览器的无限可能 在当今数字化时代,网络浏览器已经成为我们日常生活中不可或缺的一部分。而随着技术的不断进步,浏览器的功能和性能也在不断提升。微软Edge作为微软推出的全新一代浏览器,引领着浏览…...

JavaScript表达式和运算符
表达式 表达式一般由常量、变量、运算符、子表达式构成。最简单的表达式可以是一个简单的值。常量或变量。例:var a10 运算符 运算符一般用符号来表示,也有些使用关键字表示。运算符由3中类型 1.一元运算符:一个运算符能够结合一个操作数&…...

爬虫实训案例:中国大学排名
近一个月左右的时间学习爬虫,在用所积累的知识爬取了《中国大学排名》这个网站,爬取的内容虽然只是可见的文本,但对于初学者来说是一个很好的练习。在爬取的过程中,通过请求数据、解析内容、提取文本、存储数据等几个重要的内容入…...

C++ IO流
C标准IO流 使用cout进行标准输出,即数据从内存流向控制台(显示器)使用cin进行标准输入,即数据通过键盘输入到程序中使用cerr进行标准错误的输出使用clog进行日志的输出 C文件IO流 文件流对象 ofstream:只写 ofstream 是 C 中用于输出文件…...

debian nginx upsync consul 实现动态负载
1. consul 安装 wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg echo "deb [signed-by/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_r…...

前端基础入门三大核心之HTML篇 —— 同源策略的深度解析与安全实践
前端基础入门三大核心之HTML篇 —— 同源策略的深度解析与安全实践 一、同源策略:定义与起源1.1 定义浅析1.2 何为“源”?1.3 起源与意义 二、同源策略的运作机制2.1 限制范围2.2 安全边界 三、跨越同源的挑战与对策3.1 JSONP3.2 CORS3.3 postMessage 四…...

go 微服务框架 kratos 日志库使用方法及原理探究
一、Kratos 日志设计理念 kratos 日志库相关的官方文档:日志 | Kratos Kratos的日志库主要有如下特性: Logger用于对接各种日志库或日志平台,可以用现成的或者自己实现Helper是在您的项目代码中实际需要调用的,用于在业务代码里…...