【Linux】详解信号的保存信号屏蔽字的设置

news2024/12/27 14:38:12

一、信号处理的一些常见概念

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

 二、信号保存以及阻塞的内核级理解

在进程的PCB中,其实是有三张表。

        一张为block位图(阻塞位图),也就是一个32位的整形变量,其中取高31位来表示是否阻塞对应的信号,比如说block位图中第0个比特位不用,第1个比特位表示是否阻塞1号信号,第一个比特位为1就表示阻塞1号信号,为0就表示不阻塞1号信号,依次类推,第2到第31个比特位也是同样的道理。

        一张为pending位图(未决位图),也是一个32位的整形变量,其中取高31位来表示是否收到对应的信号,比如说pending位图中第0个比特位不用,第1个比特位表示是否收到1号信号,第一个比特位为1就表示收到1号信号,为0就表示没有收到1号信号。

        另一张是一个函数指针数组,该数组中每一个下标中都存放了收到对应信号后的处理方法。如果我们不对方法做自定义写入,那么进程在收到对应信号后执行的就是默认的方法,如果自定义写入了那执行的就是我们写入的方法。

        在上图中,三个数组(前两张位图也可以看成数组)应该横着看,依次表示该信号是否被阻塞,是否收到该信号,以及执行该信号的处理方法。 常规信号在递达之前产生多次只计一次,也就是说,当在一段时间内有多个相同的信号到来但却来不及被处理时,在pending位图里只会记录一次而实时信号在递达之前产生多次可以依次放在一个队列里。

三、查看pending位图

        其中sigset_t类型的解释就在下面,set为一个输出型参数,我们传入一个sigset_t类型的参数set,pending位图中的值就被set参数获得了。如果获取成功sigpending函数返回0,是被返回-1。

四、设置信号屏蔽字操作(修改block位图)

        从上面的介绍中我们也可以看到,其实block位图和pending位图的结构是十分相似的,所以未决和阻塞标志可以用相同的数据类型sigset_t来存储,sigset_t称为信号集,可以用来修改进程block位图中的信号屏蔽字sigset_t就是一种数据类型,跟int、double这些数据类型没有区别。

3.1、信号集操作函数

        sigset_t虽然是一种数据类型,但是我们并不能直接手动的修改sigset_t类型的值,必须要调用对应的系统调用函数。

#include <signal.h>
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset (sigset_t *set, int signo);
int sigdelset(sigset_t *set, int signo);
int sigismember(const sigset_t *set, int signo);
  • sigemptyset:初始化set所指向的信号集,使其中所有信号的对应bit清零,表示该信号集不包含任何有效信号。
  • sigfillset:初始化set所指向的信号集,使其中所有信号的对应bit置1位,表示该信号集的有效信号包括系统支持的所有信号。
  • sigaddset:在set信号集中添加signo信号。
  • sigdelset:在set信号集中删除signo信号。
  • sigismember:用于测试一个指定的信号是否已加入至一个特定的信号集中。

        我们设置完信号集set的值后,set并没有被设置进进程的PCB中,还需要我们调用系统调用函数设置。 

 3.2、设置信号屏蔽字

利用sigprocmask系统调用函数可以设置进程的信号屏蔽字

第一个参数how有三个选项:

  • SIG_BLOCK:set包含了我们希望添加到当前信号屏蔽字中的信号,相当于mask=mask|set。
  • SIG_UNBLOCK:set包含了我们希望从当前信号屏蔽字中解除阻塞的信号,相当于mask=mask&~set。
  • SIG_SETMASK:设置当前信号屏蔽字为set所指向的值,相当于mask=set。

        第二个参数set是我们设置的信号屏蔽字,第三个参数为输出型信号屏蔽字,是原来的信号屏蔽字。 

3.3、设置信号屏蔽字的例子

        下面是一个设置屏蔽2号信号,有解除屏蔽2号信号的例子。在程序运行起来到程序运行到20秒期间,我给程序发送2号信号,应该看到pending位图中2号信号的位置为1但程序不退出,到了20秒时程序退出。

        下面是打印pending表的函数,如果收到信号,对应的比特位就置1,如果没有收到就置0。

void print(const sigset_t& pending)
{
    for(int i = 31; i>=1; i--)
    {
        if(sigismember(&pending, i))
            std::cout << "1";
        else
            std::cout << "0";
    }
    std::cout << std::endl;
}

 2号信号加入到信号屏蔽集中:

    sigset_t set, oldset;
    sigemptyset(&set);
    sigemptyset(&oldset);

    sigaddset(&set, 2);//将2号信号加入到要屏蔽的信号集中

 set设置进进程的PCB中:

    //设置set进block位图中
    int n = sigprocmask(SIG_SETMASK, &set, &oldset);
    if(n == -1)
    {
        std::cout << "设置屏蔽字错误!" << std::endl;
        return 1;
    }

查看pending表,观察退出状态:

    int cnt = 0;

    //查看pending位图,给进程发送2号信号,pending位图中应该出现2号信号,但是进程不会退出
    //等到20秒时程序退出
    while(true)
    {
        cnt++;
        if(cnt == 20)
            sigprocmask(SIG_UNBLOCK, &set, &oldset);
        sigset_t pending;
        sigemptyset(&pending);
        int m = sigpending(&pending);
        print(pending);
        sleep(1);
    }

发送2号信号,程序到20秒时退出: 

四、总结

        31个信号中并不是所有信号都可以被屏蔽掉,9号信号(SIGKILL)和19号信号(SIGSTOP)是无法被屏蔽掉的。若想获取上述的完整的代码,请移步本人码云:240427 · 沈旭彬/C++代码 - 码云 - 开源中国 (gitee.com) 

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

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

相关文章

传感器测试脉冲电源 —测试传感器性能的电源设备

传感器测试脉冲电源是一种专门用于测试传感器性能的电源设备。传感器测试脉冲电源可以输出不同幅值、频率和形状的脉冲信号&#xff0c;以模拟传感器在实际应用中可能遇到的各种电压和电流波形。通过这种电源&#xff0c;可以对传感器进行全面的性能测试&#xff0c;包括动态响…

信号,信号列表,信号产生方式,信号处理方式

什么是信号 信号在我们的生活中非常常见&#xff1b;如红绿灯&#xff0c;下课铃&#xff0c;游戏团战信号&#xff0c;这些都是信号&#xff1b;信号用来提示接收信号者行动&#xff0c;但接收信号的人接收到信号会进行一系列的行为&#xff0c;完成某个动作&#xff1b;这就…

qt学习篇---界面按键关联(信号和槽)

目录 1.qt基础 2.做一个界面 创建project UI界面设计 信号和槽 1.控件改名字 2.什么是信号和槽 3.怎么关联信号和槽 自动关联 手动关联 1.qt基础 qt可移植性强&#xff0c;不久会用到MCU。很有意义学习 2.做一个界面 创建project 不要中文路径 选择QWidget .pro文件…

字符串函数与字符函数运用(1)

字符串与字符函数介绍1 前言一、字符分类函数字符函数练习 二、字符函数转换1.引入库2.代码改进 字符串函数strlen函数strcpy 结尾 前言 字符串函数大概有以下这几种 strcpy、strcat 、strcmp、strncpy、strncat、strncmp、strstr、strtok、strerror 这些函数可以很好的解决你…

数据结构的队列(c语言版)

一.队列的概念 1.队列的定义 队列是一种常见的数据结构&#xff0c;它遵循先进先出的原则。类似于现实生活中排队的场景&#xff0c;最先进入队列的元素首先被处理&#xff0c;而最后进入队列的元素则要等到前面的元素都被处理完后才能被处理。 在队列中&#xff0c;元素只能…

什么,你的EasyExcel导出一万条数据就OOM了?

前言 前段时间在做一个导出的功能&#xff0c;本以为是平平无奇的一个功能。就用公司内部的一个导出工具类三下五除二就写完了&#xff0c;做法是直接查全量数据&#xff0c;然后直接往Excel里写。一开始没多少数据也没什么问题&#xff0c;但是当数据量逐渐多了起来后&#x…

【OpenCV • c++】图像平滑处理(2) —— 方框滤波 | 盒滤波 | 源码分析

文章目录 前言一、方框滤波代码演示 二、源码分析 前言 前文我们了解了什么是图像平滑处理、图像滤波、邻域算子与线性邻域滤波、以及如何使用方框滤波&#xff0c;本文我们来分析一下方框滤波的源码。 一、方框滤波 void boxFilter(InputArray src, OutputArray dst, int ddep…

面试常见 | 项目上没有亮点,如何包装?

很多技术人在公司用的老技术&#xff0c;而且很多都是搬业务代码且做枯燥乏味的CRUD&#xff0c;在面试提交简历或做自我介绍的时候并不突出&#xff0c;这种情况&#xff0c;如何破局&#xff1f; 首先不管你做的啥项目&#xff0c;全世界不可能只有你自己在做&#xff0c;比…

Android Handler用法

Android Handler用法 为什么要设计Handler机制&#xff1f;Handler的用法1、创建Handler2、Handler通信2.1 sendMessage 方式2.2 post 方式 Handler常用方法1、延时执行2、周期执行 HandlerThread用法主线程-创建Handler子线程-创建Handler FAQMessage是如何创建主线程中Looper…

Agent AI智能体的未来

未来社会中的智能使者&#xff1a;Agent AI智能体的可能性与挑战 随着科技的迅速进步&#xff0c;人工智能已深入我们生活的各个领域&#xff0c;而Agent AI智能体作为与人工智能紧密相关的一个分支&#xff0c;其未来发展无疑是值得期待的。Agent AI智能体&#xff0c;或称为…

JAVA Coding 规范

Coding 规范 文章目录 Coding 规范一.文件规范1.1 声明1.2 缩进1.3 空行1.4 空格1.5 对齐1.6 小括号1.7 花括号1.8 代码长度 二.命名规范2.1 命名总则2.2 命名空间2.3 类与接口2.4 方法命名2.5 属性命名2.6 常量命名2.7 变量命名 三.语句规范3.1 语句总则3.2 循环语句3.3 Switc…

【note3】linux驱动基础,

文章目录 1.互斥锁和自旋锁选择&#xff1a;自旋锁&#xff08;开销少&#xff09;的自旋时间和被锁住的代码执行时间成正比关系2.linux错误码&#xff1a;64位错误指针指向内核空间最后一页&#xff0c;对于 1.互斥锁和自旋锁选择&#xff1a;自旋锁&#xff08;开销少&#x…

QT:核心控件-QWidget

文章目录 控件enableobjectNamegeometrysetWindowTitleopacitycursorFonttooltipstyleSheet 控件 什么是控件&#xff1f; 如上所示&#xff0c;就是控件&#xff0c;而本篇要做的就是对于这些控件挑选一些比较有用的常用的进行讲解分析 在QT的右侧&#xff0c;会有对应的空间…

【面试经典 150 | 分治】将有序数组转换为二叉搜索树

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;中序遍历递归建树 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题涉及到的数据结构等…

如何有效地合并和分类多个文件目录?

在现代办公环境中&#xff0c;文件管理和组织是至关重要的。随着科技的发展&#xff0c;我们不再仅仅依赖于纸质文件&#xff0c;而是更多地使用电子设备来存储和管理信息。这种转变带来了一些新的挑战&#xff0c;其中之一就是如何有效地合并和分类多个目录文件。一&#xff0…

Sortable 拖拽行实现el-table表格顺序号完整例子,vue 实现表格拖拽行顺序号完整例子

npm install sortable<template><vxe-modalref"modalRef"v-model"showModal"title"详情"width"70vw"height"60vh"class"his"transfer><el-table ref"tableRef" :data"tableData&q…

树莓派5用docker运行Ollama3

书接上回&#xff0c;树莓派5使用1panel安装 Ollama 点击终端就可以进入容器 输入以下代码 ollama run llama3Llama3 是市场推崇的版本。您的 树莓派5上必须至少有 4.7GB 的可用空间&#xff0c;因此用树莓派玩机器学习就必须配置大容量的固态硬盘。用1panel部署网络下载速度…

4G远程温湿度传感器在农业中的应用—福建蜂窝物联网科技有限公司

解决方案 农业四情监测预警解决方案 农业四情指的是田间的虫情、作物的苗情、气候的灾情和土壤墒情。“四情”监测预警系统的组成包括管式土壤墒情监测站、虫情测报灯、气象站、农情监测摄像机&#xff0c;可实时监测基地状况,可以提高监测的效率和准确性&#xff0c;为农业生…

“Unite“ > MacOS下很不错的网站转应用App的工具

前言 前不久在浏览mac论坛&#xff0c;无意了解到一款非常好的工具&#xff0c;可以将网站转换为app&#xff0c;考虑到我们现在的主要应用都从本地客户端转成web形式使用&#xff0c;但基于本能的使用习惯&#xff0c;还是希望有个快捷的访问信息&#xff0c;这个应用非常适合…

202012青少年软件编程(Python)等级考试试卷(一级)

第 1 题 【单选题】 运行下方代码段&#xff0c;输出是6&#xff0c;则输入的可能是&#xff08; &#xff09;。 a eval(input())print(a)A :8%2 B :8/2 C :3*2 D :3**2 正确答案:C 试题解析: 第 2 题 【单选题】 关于Python变量&#xff0c;下列叙述正确的是&#x…