【Linux】进程信号保存

前言

上篇博客我们了解了进程信号的概念和信号如何产生。
本篇我们将学习进程信号如何保存。

在这里插入图片描述

文章目录

  • 前言
  • 一. 阻塞信号
  • 二. 递达动作
  • 三. 信号集
  • 四. 信号集操作函数
  • 结束语

一. 阻塞信号

首先我们需要一些预备知识

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

并且pcb的task_struct内部其实维护有三张表
在这里插入图片描述

  1. pending 表位图结构。 比特位的位置,表示哪一个信号;比特位的内容,代表是否收到该信号
  2. block 表位图结构。比特位的位置,表示哪一个信号;比特位的内容,代表对应的信号是否需要被阻塞
  3. handler 表函数指针数组,内部的函数指针,是有一个int的参数,返回值是void 的函数指针
    该数组的下标,代表信号编号,数组的特定下标的内容,表示该信号的递达动作

二. 递达动作

在上一篇我们说进程对一个信号的处理有三种:默认动作,自定义动作,忽略
我们讲了自定义动作,其实就是我们自己编写,返回值是void,有一个int参数的函数,并用signal函数对特定信号进行捕捉。
而默认动作和忽略其实是在这样的
在这里插入图片描述
默认动作是SIG_DFL,忽略是SIG_IGN
二者其实都是将整型强转成函数指针类型,其中SIG_DFL就是Default action终止进程

三. 信号集

未决和阻塞标志可以用相同的数据类型sigset_t来存储,sigset_t称为信号集,这个类型可以表示每个信号的“ 有效 ”或“ 无效 ”状态,在阻塞信号集中“ 有效 ”和“ 无效 ”的含义是该信号是否被阻塞,而在未决信号集中“ 有效 ”和“ 无效 ”的含义是该信号是否处于未决状态。
阻塞信号集也叫做当前进程的信号屏蔽字(Signal Mask),这里的“屏蔽”应该理解为阻塞而不是忽略。

操作系统给我们提供了信号集类型
在这里插入图片描述

sigset其实也是位图,是长度更长的位图,因为一个unsigned long int 是4字节,也就是32位,而使用数组结构,就可以有更多的比特位了。
假如要访问第127位,是这样操作的
-val[ 127 / (sizeof( unsigned long int ) * 8 ) ],表示访问第3个unsigned long int
再访问127 % (sizeof( unsigned long int ) *8)

但是,我们不需要这样操作,操作系统给我们提供了相应操作的函数

四. 信号集操作函数

#include <signal.h> 头文件
int sigemptyset (sigset_t *set); 将所有比特位都置为0
int sigfillset (sigset_t *set); 将所有比特位都置为1
int sigaddset (sigset_t *set, int signo); 添加第signo位信号
int sigdelset (sigset_t *set, int signo); 删除第signo位信号
int sigismember(const sigset_t *set, int signo); 判断signo信号是否则在该位图里

sigprocmask()

可以读取或更改进程的信号屏蔽字(阻塞信号集)
在这里插入图片描述

oset是输出型参数,返回旧的sigset_t,修改后可直接恢复
如果oset是非空指针,则读取进程的当前信号屏蔽字通过oset参数传出。如果set是非空指针,则更改进程的信号屏蔽字,参数how指示如何更改。
如果oset和set都是非空指针,则先将原来的信号屏蔽字备份到oset里,然后根据set和how参数更改信号屏蔽字。假设当前的信号屏蔽字为mask,how参数有如下几个可选值

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

以下实验我们对2号信号进行阻塞,并且可以获取原先的block表和改变后的block表

在这里插入图片描述

我们给set添加2号信号,然后再将使用SIG_SETMASK将set直接赋值给当前进程的block表,这样就成功阻塞了2号信号。从结果看到,我们在程序运行时,即使使用ctrl+c也无法终止进程。
然后前5次打印oset,我们是打印原先的block表,在第6次循环时,我们再获取当前进程的block表,可以发现,2号位置为1,表明2号信号被阻塞了。


sigpending()
在这里插入图片描述

sigpending()函数可以获取当前进程的pending表

sigset_t * set:输出型参数,会将当前进程的pending表赋值给set

接下来我们再做一个实验,也是阻塞2号信号,同时我们获取pending表,然后发送2号信号,观察变化

#include<iostream>
#include<cassert>
#include<signal.h>
#include<unistd.h>

using namespace std;

//打印pending表
void printPending(const sigset_t &pending)
{
    for(int signo=1;signo<=31;signo++)
    {
        //查询pending表内是否有signo号信号
        if(sigismember(&pending,signo))
        {
            cout<<1;
        }
        else
        {
            cout<<0;
        }
    }
    cout<<endl;
}

int main()
{
    //信号集
    //set是更改的信号集,oset获取旧的信号集
    sigset_t set,oset;
    //将两个信号集都置0
    sigemptyset(&set);
    sigemptyset(&oset);

    //添加阻塞的信号,如2号信号
    sigaddset(&set,2);

    //阻塞信号
    sigprocmask(SIG_BLOCK,&set,&oset);

    //获取pending表
    while(true)
    {
        sigset_t pending;
        sigemptyset(&pending);
        //获取pending表
        int n=sigpending(&pending);
        assert(n==0);
        (void)n;//使用一下n变量,防止release版本assert被忽略,而引发的报错
        //打印pending表
        printPending(pending);
        //休眠一下
        sleep(1);
    }

    return 0;
}

结果如下:
在这里插入图片描述

可以看到,pending 表最开始是全0,也就是一个信号都没有收到,而当我们按下了ctrl+c,也就是发送了2号信号,可以看到pending表第2位变成了1,又因为我们对2号信号进行了阻塞,所以进程即使收到2号信号,pending表2号位置变成1,但是还是没有终止进程,因为我们阻塞了2号信号,进程并不会执行相应的动作。并且因为2号信号没有处理,所以pending表中2号位置一直为1。

同时,我们也可以阻塞一段时间后,再使用sigprocmask恢复原先的block表
在这里插入图片描述

结束语

本篇内容到此就结束了,感谢你的阅读!

如果有补充或者纠正的地方,欢迎评论区补充,纠错。如果觉得本篇文章对你有所帮助的话,不妨点个赞支持一下博主,拜托啦,这对我真的很重要。
在这里插入图片描述

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

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

相关文章

数字图像处理-绪论

数字图像处理-绪论 文章目录 前言一、闲谈二、什么是数字图像处理&#xff1f;2.1. 什么是数字图像&#xff1f;2.1.1. 可见光图像2.1.2. 不可见光图像 2.2. 什么是数字图像处理&#xff1f; 三、数字图像处理的前世今生3.1. 数字图像处理的前世3.2. 数字图像处理的今生 四、数…

【嵌入式系统】课程复习资料整理

【嵌入式系统】课程复习资料整理 一、绪论 1.定义 从技术的角度定义&#xff1a;以应用为中心、以计算机技术为基础、软件硬件可裁剪、对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。从系统的角度定义&#xff1a;嵌入式系统是设计完成复杂功能的硬件和软件&a…

使用crontab定时自动更新DDNS

需求说明&#xff1a; N1盒子的armbian系统配置好了 ipv6 的ddns&#xff0c;实现了域名访问本机&#xff0c;但是本地ipv6可能会发生变化&#xff0c;当发生变化后&#xff0c;需要手动执行指令&#xff0c;将新的ip与域名绑定&#xff0c;现在我们采用定时任务&#xff0c;每…

Nuvoton NK-980IOT开发板 u-boot 编译

前言 最近搭建了 Nuvoton NK-980IOT开发板 的开发编译环境&#xff0c;记录一下 u-boot 的 编译流程 Nuvoton NK-980IOT开发板 资源还是比较的丰富的&#xff0c;可以用于 嵌入式Linux 或者 RT-Thread 的学习开发 开发板上电比较的容易&#xff0c;两根 USB 线即可&#xff0…

计网笔记 01 概述 计算机网络体系结构、参考模型

文章目录 前言1、计网概述1.1 概念、组成、功能、分类1.1.1 概念1.1.2 计网组成1.1.2 计网分类 1.2 标准化工作及相关组织1.2.1 标准的分类 1.3 性能指标★★★1.3.1 速率相关性能指标1.3.2 时延相关指标 2、体系结构&参考模型★★★★★&#xff08;对应王道视频7-10p 相当…

Android Jetpack:利用Palette进行图片取色

与产品MM那些事 新来一个产品MM&#xff0c;因为比较平&#xff0c;我们就叫她A妹吧。A妹来第一天就指出&#xff1a;页面顶部的Banner广告位的背景是白色的&#xff0c;太单调啦&#xff0c;人家不喜欢啦&#xff0c;需要根据广告图片的内容自动切换背景颜色&#xff0c;颜色…

基于CUDA的GPU计算PI值

访问【WRITE-BUG数字空间】_[内附完整源码和文档] 基于CUDA的GPU计算PI值。本项目使用CUDA编程模型并行计算PI值&#xff0c;研究GPU与CPU效率的比较&#xff0c;分析不同GPU线程分块对性能的影响。 异构计算试验报告 —实验1&#xff1a;基于CUDA的GPU计算PI值 第一部分&…

JS逆向 -- 某平台登录加密分析

一、打开网站&#xff0c;使用账号密码登录 账号&#xff1a;aiyou123.com 密码&#xff1a;123456 二、通过F12抓包&#xff0c;抓到如下数据&#xff0c;发现密码加密了 三、加密结果是32位&#xff0c;首先考虑是md5加密。 四、全局搜索pwd&#xff0c;点击右上角&#xf…

【ros2】ros melodic迁移到ros2 dashing过程中碰到的问题及解决方法

序言 总结踩坑经历&#xff0c;以利他人 1. error: forming pointer to reference type … & 报错原因&#xff1a; ros2回调函数的参数不能是引用形式 &&#xff0c;需要去除& 解决方法&#xff1a; 如果是指针引用&#xff0c;直接去除引用 void Callback(con…

javascript中的严格模式

认识严格模式&#xff1a; 在ECMAScript5标准中&#xff0c;JavaScript提出了严格模式的概念&#xff08;Strict Mode&#xff09;: 严格模式很好理解&#xff0c;是一种具有限制性的JavaScript模式&#xff0c;从而是代码隐式的脱离了“懒散&#xff08;sloppy&#xff09;模…

软件测试实战,Web测试详细总结 (覆盖所有测试点),你要的都有

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 Web自动化测试&…

在技术圈超卷的当下,学历到底是敲门砖还是枷锁?

前言 最近&#xff0c;突然之间被“孔乙己文学”刷屏了&#xff0c;短时间内“孔乙己文学”迅速走红&#xff0c;孔乙己是中国文学中的一位经典人物&#xff0c;他的长衫被认为是他的象征之一&#xff0c;孔乙己的长衫折射出很多现象&#xff0c;既有社会的&#xff0c;也有教育…

Android平台播放透明视频

Android平台播放透明视频 思路 设计一种特殊的视频&#xff0c;它的一半内容存储alpha信息&#xff0c;另一半内容存储rgb信息&#xff0c;接着通过OpenGL获取每个像素点的alpha值和rgb值进行混合&#xff0c;最后出来的画面就是带有透明效果的视频了。 可以上下的分&#xf…

服务器中了勒索病毒,升级后的Malox勒索病毒特征,勒索病毒解密数据恢复

Mallox勒索病毒是网络上较为流行的勒索病毒&#xff0c;但是随着黑客加密技术的不断升级&#xff0c;Mallox勒索病毒的新升级版本Malox勒索病毒已经开始出现。Malox勒索病毒是一种最近在网络上广泛传播的恶意软件&#xff0c;其感染方式多种多样&#xff0c;主要以加密受害人的…

基于zookeeper实现分布式锁

目录 zookeeper知识点复习 相关概念 java客户端操作 实现思路分析 基本实现 初始化链接 代码落地 优化&#xff1a;性能优化 实现阻塞锁 监听实现阻塞锁 优化&#xff1a;可重入锁 zk分布式锁小结 zookeeper知识点复习 Zookeeper&#xff08;业界简称zk&#xff…

Zookeeper系统模型介绍

目录 一、数据模型 二、 节点的类型 &#xff08;1&#xff09;持久节点 &#xff08;2&#xff09;持久顺序节点 &#xff08;3&#xff09;临时节点 &#xff08;4&#xff09;临时顺序节点 三、客户端命令行 &#xff08;1&#xff09;创建节点 &#xff08;2&…

最新VUE面试题

前言 本文以前端面试官的角度出发&#xff0c;对 Vue 框架中一些重要的特性、框架的原理以问题的形式进行整理汇总&#xff0c;意在帮助作者及读者自测下 Vue 掌握的程度。 本文章节结构以从易到难进行组织&#xff0c;建议读者按章节顺序进行阅读&#xff0c;当然大佬级别的…

操作系统——进程管理

0.关注博主有更多知识 操作系统入门知识合集 目录 0.关注博主有更多知识 4.1进程概念 4.1.1进程基本概念 思考题&#xff1a; 4.1.2进程状态 思考题&#xff1a; 4.1.3进程控制块PCB 4.2进程控制 思考题&#xff1a; 4.3线程 思考题&#xff1a; 4.4临界资源与临…

【分布式技术专题】「授权认证体系」OAuth2.0协议的入门到精通系列之授权码模式

这里写目录标题 OAuth2.0是什么OAuth2.0协议体系的Roles角色OAuth定义了四个角色资源所有者资源服务器客户端授权服务器 传统的客户机-服务器身份验证模型的问题 协议流程认证授权授权码 OAuth2.0是什么 OAuth 2.0是用于授权的行业标准协议。OAuth 2.0专注于简化客户端开发人员…

一文介绍Linux EAS

能量感知调度&#xff08;Energy Aware Scheduling&#xff0c;简称EAS&#xff09;是目前Android手机中Linux线程调度器的基础功能&#xff0c;它使调度器能预测其决策对CPU能耗的影响。依靠CPU的能量模型&#xff08;Energy Model&#xff0c;简称EM&#xff09;&#xff0c;…