【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; // pending
    sigemptyset(&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 号信号不能被屏蔽,也不能被捕捉。

五、结语

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

在这里插入图片描述

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

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

相关文章

TikTok广告投放攻略——广告类型详解

TikTok广告是品牌或创作者付费向特定目标受众展示的推广内容&#xff08;通常是全屏视频&#xff09;。TikTok 上的广告是一种社交媒体营销形式&#xff0c;通常旨在提高广告商的知名度或销售特定产品或服务。 就 TikTok广告投放而言&#xff0c;其组织层级分为三个层级&#x…

数据库基本知识

感觉面试的时候面试官大多数都必问数据库&#xff0c;也可以理解&#xff0c;企业肯定会涉及到大规模数据存储&#xff0c;那么数据库存储就一定会用到数据库。做一些数据库相关的基本知识总结&#xff0c;持续更新~ 【死锁专题】 1.如何解决数据库并发造成的安全问题&#x…

【LeetCode 滑动窗口】LC_3_无重复字符的最长子串

文章目录 1. 无重复字符的最长子串 1. 无重复字符的最长子串 题目链接&#x1f517; &#x1f34e;题目思路&#xff1a;&#x1f427;① 滑动窗口的思想&#xff1b;&#x1f427;② 用什么来维护窗口呢 &#xff1f; 用 双指针 和 unordered_set来维护&#xff0c;为什么呢…

从 LangChain 中学习检索增强

前言 之前讲了一些关于 RAG 的使用技巧和经验&#xff0c;今天我们提供两个进阶版的文本切分和检索的方法&#xff0c;希望对你有所帮助。以下两种方法取自 LangChain 的官方示例&#xff0c;感兴趣也可以直接去阅读官方文档。 一、父文档检索 Parent Document Retriever 当…

瑞萨芯片简介和工具链使用

文章目录 前言一、RH850简介二、瑞萨开发工具链1.e2studio2.IAR For RH8503.CS+ for CC4.GHS前言 瑞萨RH850 MCU家族,专为高端汽车应用而设计。MCU家族中的不同成员,如RH850/F1x、RH850/P1x、RH850/D1x、RH850/E1x和RH850/C1x,每个成员针对特定的应用领域。 RH850 F系列的…

数据结构(3)栈、队列、数组

1 栈 1.1 栈的定义 后进先出【LIFO】 1.2 基本操作 元素进栈出栈 只能在栈顶进行&#xff01;&#xff01;&#xff01; 经常考的题&#xff1a; 穿插的进行进栈和出栈 可能有多个选项 1.3 顺序栈 1.3.1 初始化 下标是从0开始的 1.3.2 进栈 更简单的写法&#xff1a; 1.3…

【经典算法】最短路径算法——Dijkstra

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;算法启示录 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 前言 松弛视角 伪代码展示 三角形理…

GlaDS缘起

题目:Modeling channelized and distributed subglacial drainage in two dimensions 近年来,冰盖表面融化与冰盖动态之间的联系及其对海平面上升的影响引起了广泛关注。特别是格陵兰冰盖的研究显示,表面融水显著影响冰川移动速度,而冰下排水系统对冰川动力学及冰川水文学…

锂电池寿命预测 | Matlab基于SSA-SVR麻雀优化支持向量回归的锂离子电池剩余寿命预测

目录 预测效果基本介绍程序设计参考资料 预测效果 基本介绍 【锂电池剩余寿命RUL预测案例】 锂电池寿命预测 | Matlab基于SSA-SVR麻雀优化支持向量回归的锂离子电池剩余寿命预测&#xff08;完整源码和数据&#xff09; 1、提取NASA数据集的电池容量&#xff0c;以历史容量作…

《尚庭公寓》项目部署之Docker + Nginx

docker rmi nginx docker pull nginx docker rm -f nginx #先创建一个简易的nginx容器&#xff08;后面会删&#xff09;&#xff0c;然后通过 docker cp命令把容器里面的nginx配置反向拷贝到宿主主机上。 docker run --name nginx -p 80:80 -d nginx# 将容器nginx.conf文件复…

[ubuntu]docker 卡登录 You‘ve been signed out

Setting->Resources->Proxies设置当前使用的proxies即可 参考&#xff1a;https://github.com/docker/for-mac/issues/7160#issuecomment-2061040813

C++ 利用模板对不同类型的数组元素排序

一、问题描述&#xff1a; 使用template函数模板对一个长度为5的int数组和char数组元素进行排序&#xff08;升序&#xff09;。 二、代码&#xff1a; #include <iostream>using namespace std;template<typename T> void swapWWW(T &a, T &b) {T c a;…

乡村振兴与脱贫攻坚相结合:巩固拓展脱贫攻坚成果,推动乡村全面振兴,建设更加美好的乡村生活

目录 一、引言 二、巩固拓展脱贫攻坚成果 1、精准施策&#xff0c;确保稳定脱贫 2、强化政策支持&#xff0c;巩固脱贫成果 3、激发内生动力&#xff0c;促进持续发展 三、推动乡村全面振兴 1、加快产业发展&#xff0c;增强乡村经济实力 2、推进乡村治理体系和治理能力…

uniapp中父子组件的传值

1. uniapp中父子组件的传值 1.1. 父子组件的传值 通过props来实现, 子组件通过props来接收父组件传过来的值 1.1.1. 父组件 <!-- 父组件 --> <template><view><my-son :title"title" sendData"getSonData"></my-son><…

巧用docker+jmeter快速实现分布式百万级并发

分享背景 碰到的问题&#xff1a; 一个JMeter实例可能无法产生足够的负载来对你的应用程序进行压力测试&#xff5e; 解决办法&#xff1a; 1、修改jmeter配置文件里的内存堆 2、引入jmeter分布式压测 带来的问题&#xff1a; 如果我们要做分布式负载测试–我们需要1个…

win10下,python3.7安装xlrd和xlwt

win10下&#xff0c;执行import xlwt&#xff0c;结果报错 No module named xlwt。 原因&#xff1a;使用的python没有安装xlwt包。 解决方法&#xff1a; 1&#xff09;打开一个命令窗口&#xff0c;执行&#xff1a;where python&#xff0c;可以看到使用的python路径及版…

5.31.8 学习深度特征以实现判别定位

1. 介绍 尽管没有对物体的位置提供监督,但卷积神经网络 (CNN) 各层的卷积单元实际上可以充当物体检测器。尽管卷积层具有这种出色的物体定位能力,但当使用全连接层进行分类时,这种能力就会丧失。最近,一些流行的全卷积神经网络,如 Network in Network (NIN) [13] 和 Goog…

翘首以盼的抗锯齿

Antialiasing 实际的图形学中是怎么实现反走样的呢&#xff1f; 我们不希望实际产出的图形有锯齿效果&#xff0c;那怎么办呢&#xff1f; 从采样的理论开始谈起吧 Simpling theory 照片也是一种采样&#xff0c;把景象打散成像素放到屏幕上的过程&#xff1a; 还可以在不…

stm32 定时器输出比较(OC)与PWM的理解和应用

不积跬步&#xff0c;无以至千里&#xff1b;不积小流&#xff0c;无以成江海。大家好&#xff0c;我是闲鹤&#xff0c;公众号 xxh_zone&#xff0c;十多年开发、架构经验&#xff0c;先后在华为、迅雷服役过&#xff0c;也在高校从事教学3年&#xff1b;目前已创业了7年多&am…

盛夏之约,即将启程,2024中国北京消防展将于6月26举行

盛夏之约&#xff0c;即将启程&#xff0c;2024中国北京消防展将于6月26举行 盛夏之约&#xff0c;即将启程&#xff01;备受瞩目的2024中国&#xff08;北京&#xff09;消防技术与设备展览会将于6月26-28 日在北京.首钢会展中心盛大召开。作为消防安全和应急救援的年度盛会&…