【Linux取经路】信号的发送与保存

在这里插入图片描述

文章目录

  • 一、重新理解发送信号
  • 二、信号的保存、阻塞信号的概念
  • 三、信号集操作函数
    • 3.1 sigprocmask
    • 3.2 sigpending
  • 四、阻塞信号代码验证
  • 五、结语

一、重新理解发送信号

进程通过位图来实现对普通信号(1-31号信号)的保存,该位图保存在进程的 task_struct 结构体中。比特位的内容是 0 还是 1,表明是否收到信号;比特位的位置是第几个,表明信号的编号。**发送信号的本质就是,操作系统去修改 task_struct 的信号位图中对应的比特位。**因为操作系统是进程的管理者,所以只能由操作修通去执行修改动作。由于对普通信号采用的是位图结构,所以对于某一个特定的信号,只能保存一次,即进程先收到了一个 2 号信号,还没有对 2 信号处理,此时又收到一个 2 号信号,因为位图只能确定进程是否少到了某一个信号,无法确定收到某个信号的个数,所以,最终 2 号信号只能被执行一次。对实时信号采用的是队列进行管理,实时信号需要立即处理,并且操作系统发了多少个实时信号,对应的进程就要处理多少次。

**操作系统本来可以直接杀掉或者暂停一个进程,那为什么还要搞出信号这一套东西呢?**答案是,操作系统还要考虑上层用户,在异常产生的时候,如果操作系统直接就把程序终止了,那历史上可能产生了很多重要的数据没有保存,导致数据丢失,操作系统为了避免承担责任,所以有了信号这一概念。在进程出现异常的时候,操作系统先给进程发送信号,相当于是给它提个醒,你已经出异常了,快干收尾工作吧,这也是信号捕捉方法里需要完成的工作。

二、信号的保存、阻塞信号的概念

信号相关概念

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

image-20240309085224850

SIG_DEFL:执行信号的默认处理动作;SIG_IGN:对信号执行忽略动作。

image-20240309090948325

三、信号集操作函数

sigset_t 称为信号集,是操作系统给用户提供的一种数据类型,用来描述和 blockpending 一样的位图,于此同时,操作系统还给我们提供了很多信号集操作函数,我们可以通过这些函数去修改信号集。

#include <signal.h>
int sigemptyset(sigset_t *set); // 将位图全部设置为 0
int sigfillset(sigset_t *set); // 将位图全部都设置为 1
int sigaddset (sigset_t *set, int signo); // 将位图中的某一位设置为 1
int sigdelset(sigset_t *set, int signo); // 将位图中的某一位设置为 0
int sigismember(const sigset_t *set, int signo); // 判断一个信号是否在信号集中,不在返回0,在返回1,出错返回-1

3.1 sigprocmask

该函数是专门针对系统中的 block 位图的。

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

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

选项含义
SIG_BLOCKset 包含了我们希望添加到当前信号屏蔽子中的信号,相当于 `mask = mask
SIG_UNBLOCKset 包含了我们希望从当前信号屏蔽字中解除阻塞的信号,相当于 mask = mask& (~set)
SIG_SETMASK设置当前信号屏蔽子为 set 所指向的值,相当于 mask = set

3.2 sigpending

该函数是专门针对系统中的 pending 位图的。

#include <signal.h>
int sigpending(sigset_t *set);

读取当前进程的未决信号集,通过 set 参数传出。调用成功返回 0,调用失败返回 -1。

四、阻塞信号代码验证

#include <iostream>
#include <signal.h>
#include <unistd.h>using namespace std;void PrintPending(const sigset_t &pset)
{for(int i = 31; i >= 1; i--){cout << sigismember(&pset, i);}cout << endl;
}void handler(int signum)
{cout << "catch a signum: " << signum << endl;
}int main()
{signal(2, handler);// 1. 先对 2 号信号进行屏蔽// 数据预备工作sigset_t bset, oset; sigemptyset(&bset); // 先将信号集清空sigemptyset(&oset); // 先将信号集清空sigaddset(&bset, 2); // 给 bset 中添加上 2 号信号// 调用系统调用,将数据设置进内核sigprocmask(SIG_SETMASK, &bset, &oset);// 2. 重复打印当前进程的 pending 信号集// 在重复打印期间向进程发送 2 号信号,因为 2 号信号被屏蔽了,所以 2 号信号会一直被保存在 pending 中sigset_t pset; // pendingsigemptyset(&pset);int cnt = 0;while(true){int n = sigpending(&pset);if(n < 0) continue;PrintPending(pset);sleep(1);cnt++;if(cnt == 15){cout << "unblock 2 signo" << endl;// 解除阻塞sigdelset(&bset, 2);sigprocmask(SIG_SETMASK, &oset, nullptr);}}return 0;
}

image-20240309102707014

9 号和 19 号信号不能被屏蔽,也不能被捕捉。

五、结语

今天的分享到这里就结束啦!如果觉得文章还不错的话,可以三连支持一下,春人的主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是春人前进的动力!

在这里插入图片描述

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

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

相关文章

冯喜运:6.7今日黄金原油行情分析及独家操作策略

【黄金消息面分析】&#xff1a;周三&#xff08;6月5日&#xff09;&#xff0c;金价回升逾1.2%&#xff0c;收盘报每盎司2,355.49美元&#xff0c;全面收复前一交易日的跌幅。周三当天前公布的美国民间就业数据弱于预期&#xff0c;增强了美联储将在今年晚些时候降息的预期&a…

多表连接查询和子查询

一、连接查询 连接查询是SQL语言最强大的功能之一&#xff0c;它可以执行查询时动态的将表连接起来&#xff0c;然后从中查询数据。 1.1、连接两表的方法 在SQL中连接两表可以有两种方法&#xff0c;一种是无连接规则连接&#xff0c;另一种是有连接规则连接。 无连接规则连…

PbootCms微信小程序官网模版/企业官网/社交电商官网/网络工作室/软件公司官网

在数字化时代&#xff0c;企业网站已成为吸引潜在客户、提升企业形象、和扩大品牌影响力的必备工具。因此&#xff0c;一个优秀的企业网站模板显得尤为重要。 企业官网的内容框架通常都包含企业形象、产品或服务类型、信息展示等部分&#xff0c;设计师需要借助和企业形象契合…

初学者如何对大模型进行微调?

粗略地说&#xff0c;大模型训练有四个主要阶段&#xff1a;预训练、有监督微调、奖励建模、强化学习。 预训练消耗的时间占据了整个训练pipeline的99%&#xff0c;其他三个阶段是微调阶段&#xff0c;更多地遵循少量 GPU 和数小时或数天的路线。预训练对于算力和数据的要求非…

【vue3|第6期】如何正确地更新和替换响应式对象reactive

日期&#xff1a;2024年6月5日 作者&#xff1a;Commas 签名&#xff1a;(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释&#xff1a;如果您觉得有所帮助&#xff0c;帮忙点个赞&#xff0c;也可以关注我&#xff0c;我们一起成长&#xff1b;如果有不对的地方&#xff…

区间预测 | Matlab实现QRCNN-GRU-Attention分位数回归卷积门控循环单元注意力机制时序区间预测

区间预测 | Matlab实现QRCNN-GRU-Attention分位数回归卷积门控循环单元注意力机制时序区间预测 目录 区间预测 | Matlab实现QRCNN-GRU-Attention分位数回归卷积门控循环单元注意力机制时序区间预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现QRCNN-GRU-…

eNSP学习——配置RIP的版本兼容、定时器和协议优先级

目录 主要命令 原理概述 实验内容 实验拓扑 实验目的 实验编址 实验步骤 1、基本配置 2、配置RIP协议的版本兼容 3、配置RIP的定时器 4&#xff0e;配置RIP协议优先级 需要eNSP各种配置命令的点击链接自取&#xff1a;华为&#xff45;NSP各种设备配置命令大全PDF版…

二重,三重积分和曲面,曲线积分的关系和区别

这是我在学习完曲面曲线积分概念后容易和二重三重积分混淆而大概总结和区分了一下&#xff0c;如果有错误请大佬指出&#xff0c;多谢&#xff01;&#xff01;&#xff01;

CopilotKit:开源 Copilot 框架,部署应用内 AI 代理,使用 Langchain 自动执行任何任务!

原文链接&#xff1a;&#xff08;更好排版、视频播放、社群交流、最新AI开源项目、AI工具分享都在这个公众号&#xff01;&#xff09; CopilotKit&#xff1a;开源 Copilot 框架&#xff0c;部署应用内 AI 代理&#xff0c;使用 Langchain 自动执行任何任务&#xff01; &am…

WPS表格插件方方格子【凑数】功能:选出和等于固定数字的数

文章目录 后来发现可以下载方方格子插件&#xff0c;使用【凑数】功能https://ffcell.lanzouj.com/iwhfc1kjhayh【凑数】快速【凑数】 导师让沾发票&#xff0c;需要选出若干个数额的发票&#xff0c;使它们的和等于一个指定数。不知道怎么办了&#xff0c;查了一下&#xff0c…

SOA的发展历史

1.SOA的发展历程 回顾SOA发展历程&#xff0c;我们把其大致分为了三个阶段&#xff0c;下面将分别介绍每个阶段的重要标准和规范。 1.1.萌芽阶段 这一阶段以XML技术为标志&#xff0c;时间大致从20世纪90年代末到21世纪初。XML系W3C所建&#xff0c;源自流行的标准通用标记语…

Xcode 打包报错Command PhaseScriptExecution failed with a nonzero exit code

解决办法: 1、在Xcode项目中 Pods -> Targets Support Files -> Pods-项目名 -> Pods-项目名-frameworks 中(大约在第44行) 加上 -f 2、CocoaPods版本太旧了,可以尝试升级CocoaPods版本 使用sudo gem update cocoapods更新cocoapods&#xff0c;问题将在1.12.1版本已…

shell的编程方式

文章目录 变量俩种方式第一种方式第二种方式 取消变量数组创建数组获取数组元素的方式 read输出的方式限制输入的方式 流程控制方式for循环输出的方式第一种方式第二种方式while循环输出的方式select选择输出的方式 判断方式判断的四种方式第一种方式第二种方式第三种方式 算术…

Docker笔记-解决非交互式运行python时print不输出的问题

换句话来说就是在docker中如何不会python的print 只需要在启动时&#xff0c;不让python缓冲其输出。 关键命令如下&#xff1a;PYTHONUNBUFFERED1 如下&#xff1a; docker run -e PYTHONUNBUFFERED1 <your_image> 下面解释下-e "-e"选项的全称是"…

【软件项目管理篇】怎样平衡软件质量与时间成本范围的关系?

你会发现&#xff0c;在实际的软件项目中不乏这样的例子&#xff1a; 一个项目&#xff0c;正常估算&#xff0c;要三个月才能完成&#xff0c;但是老板或客户要压缩到一个月完成&#xff0c;而你不知道如何说服他们&#xff1b;项目开发一半&#xff0c;产品经理告诉你&#…

Python-GEE遥感云大数据分析、管理与可视化及多领域案例教程

原文链接&#xff1a;Python-GEE遥感云大数据分析、管理与可视化及多领域案例教程https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247606139&idx3&sn2b98c8d5c99878ce78c8fade559bdae5&chksmfa821e9ccdf5978a7e63a1d514f2a643158a595fa75ac751c5ca47769…

socket网络编程——多进程、多线程处理并发

如下图所示, 当一个客户端与服务器建立连接以后,服务器端 accept()返回,进而准备循环接收客户端发过来的数据。 如果客户端暂时没发数据,服务端会在 recv()阻塞。此时,其他客户端向服务器发起连接后,由于服务器阻塞了,无法执行 accept()接受连接,也就是其他客户端发送…

MySQL存储引擎的区别和比较

MyISAM存储引擎 MyISAM基于ISAM存储引擎&#xff0c;并对其进行扩展。它是在Web、数据仓储和其他应用环境下最常使用的存储引擎之一。MyISAM拥有较高的插入、查询速度&#xff0c;但不支持事务。 MyISAM主要特性有&#xff1a; 1、大文件&#xff08;达到63位文件长度&#x…

信号:干扰类别及特征提取

目录 第一部分&#xff1a;干扰类别 1.压制干扰 1.1噪声调幅瞄准式干扰(单音干扰) 1.2噪声调频阻塞式干扰&#xff08;宽带噪声干扰&#xff09; 1.3噪声调频扫频式干扰&#xff08;线性调频&#xff09; 2.欺骗干扰 2.1距离欺骗干扰&#xff08;幅度调制干扰&#xff0…

前端_调试工具_Chrome Devtools

目录 一、上左侧菜单功能 1.选择功能 2.手机/电脑 显示切换功能 3.内存 4.元素 5.控制台 6.源代码/来源 7.网络 8.应用 9.性能 10.安全 11.Lighthouse 12.记录器 13.性能数据分析 二、上右侧菜单功能 1.警告 2.设置 3....更多功能 谷歌浏览器自带了调试工具C…