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

news2024/11/23 23:35:10

在这里插入图片描述

文章目录

  • 一、重新理解发送信号
  • 二、信号的保存、阻塞信号的概念
  • 三、信号集操作函数
    • 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 号信号不能被屏蔽,也不能被捕捉。

五、结语

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

在这里插入图片描述

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

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

相关文章

DSP28335模块配置模板系列——ADC配置模板

一、配置步骤 1.使能并配置高速时钟HSPCLK、ADC校验 EALLOW;SysCtrlRegs.PCLKCR0.bit.ADCENCLK 1; EDIS;EALLOW;SysCtrlRegs.HISPCP.all ADC_MODCLK; // HSPCLK SYSCLKOUT/(2*ADC_MODCLK)ADC_cal();EDIS; 这里ADC_MODCLK3&#xff0c;所以HSPCLK时钟为150/625Mhz 2.配…

C语言基础——数组(2)

ʕ • ᴥ • ʔ づ♡ど &#x1f389; 欢迎点赞支持&#x1f389; 个人主页&#xff1a;励志不掉头发的内向程序员&#xff1b; 专栏主页&#xff1a;C语言基础&#xff1b; 文章目录 前言 一、二维数组的创建 1.1 二维数组的概念 1.2二维数组的创建 二、二维数组…

javascript导入excel文件

导入文件用到一个 xlsx.core.js 的包。 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><script type"tex…

晶振时钟外设总线

如果芯片只有一个时钟信号脚怎么接晶振&#xff1f; 答&#xff1a;如果芯片只有一个时钟信号引脚&#xff0c;说明这是一个时钟输入脚&#xff08;OSC IN&#xff09;&#xff0c;为有源晶振&#xff08;晶体振荡器&#xff09;应用方案&#xff0c;请选择有源晶振并连接其时…

AMD显卡和英伟达显卡哪个好?

显卡是计算机中负责处理图形和视频输出的硬件设备&#xff0c;主要分为两种类型&#xff1a;AMD的A卡和NVIDIA的N卡。那么AMD显卡和英伟达显卡哪个好&#xff1f;怎么选&#xff1f; 答&#xff1a;不能一概而论地说哪个好&#xff0c;因为它们各有优势&#xff0c;选择应基于…

echaerts图例自动滚动并隐藏翻页按钮

效果图 代码 legend: {itemHeight: 14,itemWidth: 14,height: "300", //决定显示多少个// 通过 CSS 完全隐藏翻页按钮pageButtonItemGap: 0,pageButtonPosition: end,pageIconColor: transparent, // 隐藏翻页按钮pageIconInactiveColor: transparent, // 隐藏翻页按…

2024050501-重学 Java 设计模式《实战命令模式》

重学 Java 设计模式&#xff1a;实战命令模式「模拟高档餐厅八大菜系&#xff0c;小二点单厨师烹饪场景」 一、前言 持之以恒的重要性 初学编程往往都很懵&#xff0c;几乎在学习的过程中会遇到各种各样的问题&#xff0c;哪怕别人那运行好好的代码&#xff0c;但你照着写完…

【计算机网络基础知识】

首先举一个生活化的例子&#xff0c;当你和朋友打电话时&#xff0c;你可能会使用三次握手和四次挥手的过程进行类比&#xff1a; 三次握手&#xff08;Three-Way Handshake&#xff09;&#xff1a; 你打电话给朋友&#xff1a;你首先拨打你朋友的电话号码并等待他接听。这就…

LeetCode刷题之HOT100之组合总和

2024/6/3 周一&#xff0c;工作日的第一天。昨晚梦到被导师说去实验室不积极哈哈哈&#xff0c;风扇开到二级&#xff0c;早上被吹醒。买的书马上快要到了。上午刚来准备刷题&#xff0c;结果去搞了一下数据库sql&#xff0c;做的差不多了&#xff0c;还差点格式转换就差不多出…

【WP】猿人学_13_入门级cookie

https://match.yuanrenxue.cn/match/13 抓包分析 抓包分析发现加密参数是cookie中有一个yuanrenxue_cookie 当cookie过期的时候&#xff0c;就会重新给match/13发包&#xff0c;这个包返回一段js代码&#xff0c;应该是生成cookie的 <script>document.cookie(y)(u)(a…

【Text2SQL】评估 LLM 的 Text2SQL 能力

论文&#xff1a;Evaluating the Text-to-SQL Capabilities of Large Language Models ⭐⭐⭐⭐ arXiv:2204.00498 一、论文速读 本论文尝试了多种 prompt 结构&#xff0c;并且评估了他们在 Codex 和 GPT-3 上的表现。下面介绍这些 prompt 结构&#xff1a; 二、不同的 prom…

VsQt单元测试目录的管理方式

正常项目的文件管理方式 正常项目的目录&#xff0c;是由文件系统中实际的文件夹进行分类管理的。 但是如果单元测试用实际文件夹管理的话&#xff0c;会出现问题&#xff0c;就是被测类太多了&#xff0c;用文件系统管理的话&#xff0c;不太方面查看&#xff0c;如下图所示。…

AI数字人本地算力直播怎么做?青否数字人教您快速搭建直播间!

一、青否数字人直播分为两种&#xff0c;一种是云端渲染另外一种就是本地渲染 使用本地算力来进行直播间互动&#xff0c;本地算力能够使商家拥有更低成本运营 在独立部署数字人SaaS系统后&#xff0c;其他的数字人厂商是【云服务器】【算力服务器】相结合的方式&#xff0c;以…

31|HTTP3:甩掉TCP、TLS 的包袱,构建高效网络

前面两篇文章我们分析了HTTP/1和HTTP/2&#xff0c;在HTTP/2出现之前&#xff0c;开发者需要采取很多变通的方式来解决HTTP/1所存在的问题&#xff0c;不过HTTP/2在2018年就开始得到了大规模的应用&#xff0c;HTTP/1中存在的一大堆缺陷都得到了解决。 HTTP/2的一个核心特性是…

App Inventor 2 复制屏幕功能,界面设计更便捷,避免误删组件

“复制屏幕”功能全新上线&#xff0c;中文网独有&#xff08;MIT没有此功能&#xff09;&#xff0c;可以复制屏幕中的普通组件、图片、附件、拓展、代码块。更多升级详情可查看发布日志。 下面演示一下屏幕的复制效果&#xff1a; 1、Screen1屏幕上有若干组件、及一个SQLit…

支付宝小众玩法 爱溜达的人不容错过

创建一个简单的程序来帮助用户管理他们的图片&#xff0c;例如筛选分辨率合适、尺寸适中的图片来准备上传&#xff0c;这是一个技术上合理且有益的方向。例如&#xff0c;一个Python脚本使用Pillow库来检查文件夹中图片的尺寸&#xff1a; from PIL import Image import os# 根…

如何永久擦除Android手机中的所有个人数据?

在这个数字化的时代&#xff0c;确保您的个人数据的安全和隐私至关重要。如果您计划出售或回收您的Android手机&#xff0c;了解如何正确擦除Android手机是至关重要的。本综合指南将引导您通过安全擦除Android手机的分步过程&#xff0c;以保护您的敏感信息。 手机是极其敏感的…

冲刺面试加油

1、HTML语义化&#xff1f; 对于开发者而言&#xff0c;语义化标签有着更好的页面结构&#xff0c;有利于代码的开发编写和后期的维护。 对于用户而言&#xff0c;当网络卡顿时有良好的页面结构&#xff0c;有利于增加用户的体验。 对于爬虫来说&#xff0c;有利于搜索引擎的…

vue中使用svg图像

一 、svg图像是什么 SVG&#xff08;可缩放矢量图形&#xff09;是一种图像格式&#xff0c;它以XML文档的形式存在&#xff0c;用以描述图像中的形状、线条、文本和颜色等元素。由于其基于矢量的特性&#xff0c;SVG图像在放大或改变尺寸时能够保持图形质量不受影响。这种格式…

【Altium】AD-原理图中使用多通道问题

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 解决在原理图主图中&#xff0c;对子图使用多通道命令后&#xff0c;子图未形成多个通道的问题。 2、 问题场景 客户手中的工程文件&#xff0c;主图中对子图使用了多通道命令&#xff0c;子图图纸并未形成多通道…