Linux-信号2

文章目录

  • 前言
  • 一、信号是如何保存的?
    • 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);
    • int sigpending(sigset_t *set);
    • int sigprocmask(int how, const sigset_t *set, sigset_t *oset);
      • 1.SIG_BLOCK
      • 2.SIG_UNBLOCK
      • 3.SIG_SETMASK
  • 二、学习步骤
    • 我们提出三个问题并对问题进行一一解答来进行我们的学习
      • 问题1. 如果我们将一个死循环进程的所有信号都捕捉,是不是该进程无法被退出?
      • 问题2. 如果我们将一个信号block阻塞,并发送对应信号,pending表的对应该信号bit位是不是由0置1?
      • 问题3. 如果我们将一个死循环进程的所有信号都阻塞,是不是该进程也无法被退出?
    • 1.解答问题1
    • 2.解答问题2
    • 3.解答问题3


前言

上节课我们学习了信号产生到处理过程的现象以及信号的捕捉,这节课主要学习信号的保存。
我们需要熟练使用以下函数

#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);
int sigprocmask(int how, const sigset_t *set, sigset_t *oset);
int sigpending(sigset_t *set);


一、信号是如何保存的?

上节课我们说过,信号是在进程的PCB中存储 信号的位图,而实际上,可不止有一个表(位图)。
在这里插入图片描述

block信号集是用以保存被block阻塞的信号,一般被称为信号屏蔽字(阻塞信号集),pending信号集就是我们上节课所说的那个收到信号即相对位由0置1的位图,一般被称为未决信号集

对于阻塞,这是提前预设好的,目的是为了让该进程屏蔽该信号,所以如果一个信号被阻塞,而又收到了该信号,虽然pending信号集由0置1,但是不进行delivery(信号递达:信号递达操作即信号的处理)操作。

而这两个信号集,在我们看来理解其实就是位图,但是OS将他们封装成了自定义类型sigset_t,通过这样的封装,对于我们用户就无法随心所欲地更改其信号集的数据,只能通过OS提供给我的系统接口函数。
现在来认识一下系统交给我们的一些接口函数。

int sigemptyset(sigset_t *set);

函数sigemptyset初始化set所指向的信号集,使其中所有信号的对应bit清零,表示该信号集不包含 任何有
效信号。
成功返回0,出错返回-1

int sigfillset(sigset_t *set);

函数sigfillset初始化set所指向的信号集,使其中所有信号的对应bit置位,表示 该信号集的有效信号包括系
统支持的所有信号。
成功返回0,出错返回-1

int sigaddset (sigset_t *set, int signo);

函数sigaddset用于将set所指向的信号集的signo信号置位。
成功返回0,出错返回-1

int sigdelset(sigset_t *set, int signo);

函数sigdelset用于将set所指向的信号集的signo信号置零。
成功返回0,出错返回-1

int sigismember(const sigset_t *set, int signo);

函数sigismember用于判断set所指向信号集的signo信号是否为1。
是则返回1,否则为0。

int sigpending(sigset_t *set);

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

int sigprocmask(int how, const sigset_t *set, sigset_t *oset);

函数sigprocmask用于更改block信号集,参数how为选项,该函数提供三种选项

1.SIG_BLOCK

该选项是希望在目前的信号屏蔽字添加set信号集的有效信号,相当于mask=mask|set

2.SIG_UNBLOCK

该选项是希望在目前的信号屏蔽字去除set信号集的有效信号,相当于mask=mask&(~set)

3.SIG_SETMASK

该选项就比较暴力些,相当于mask=set

而参数oset为输出型参数,用于保存老信号集。

需要注意的,在使用sigset_ t类型的变量之前,一定要调 用sigemptyset或sigfillset做初始化,使信号集处于确定的
状态。

二、学习步骤

我们提出三个问题并对问题进行一一解答来进行我们的学习

问题1. 如果我们将一个死循环进程的所有信号都捕捉,是不是该进程无法被退出?

问题2. 如果我们将一个信号block阻塞,并发送对应信号,pending表的对应该信号bit位是不是由0置1?

问题3. 如果我们将一个死循环进程的所有信号都阻塞,是不是该进程也无法被退出?

1.解答问题1

代码如下(示例):

#include<stdio.h>
#include<unistd.h>
#include<iostream>
#include<signal.h>void catchSig(int signum)
{std::cout << "pid " << getpid() <<" :捕捉到信号 " << signum << std::endl; 
}int main()
{for(int i = 1; i <= 31 ; i++){signal(i,catchSig);}while(1){std::cout << "pid " << getpid() << " :进程运行中... " <<std::endl;sleep(1);}return 0;
}

这个程序会在运行时捕捉1-31号的所有信号,那么是不是这个进程就无法退出了呢?
我们通过命令行依次输入kill命令来进行对该进程发送信号,发现在发送9号信号的时候,进程还是被终止了,说明进程的9号信号没有被捕捉!
在这里插入图片描述
所以这里的结论就是如果我们将一个死循环进程的所有信号都捕捉,该进程仍然可以通过9号信号退出,因为设计OS的人知道,如果有恶意程序真的将所有信号都可以捕捉,那么后果是十分严重的!

2.解答问题2

代码如下(示例):

#include <stdio.h>
#include <unistd.h>
#include <iostream>
#include <signal.h>
#include <assert.h>void ShowSet(sigset_t &set)
{for (int i = 1; i <= 31; i++){// 通过sigismember来打印我们的pending信号集std::cout << sigismember(&set, i);}std::cout << std::endl;
}int main()
{sigset_t set;sigset_t block;sigset_t oset;// 1.进行初始化sigemptyset(&set);sigemptyset(&block);sigemptyset(&oset);// 2.阻塞2号信号sigaddset(&block, 2);sigprocmask(SIG_BLOCK, &block, &oset);std::cout << "pid " << getpid() << std::endl;// 3.循环打印未决信号集while (1){// 3.1 获取当前的未决信号集sigpending(&set);ShowSet(set);sleep(1);}return 0;
}

在这里插入图片描述
我们很清楚的看到第二位由0置1了。
所以结论就是如果我们将一个信号block阻塞,并发送对应信号,pending表的对应该信号bit位是由0置1。

3.解答问题3

代码如下(示例):

#include <stdio.h>
#include <unistd.h>
#include <iostream>
#include <signal.h>
#include <assert.h>void ShowSet(sigset_t &set)
{for (int i = 1; i <= 31; i++){// 通过sigismember来打印我们的pending信号集std::cout << sigismember(&set, i);}std::cout << std::endl;
}void SendSig(int signum)
{if ((signum != 19) &&(signum != 9) && (signum <= 31))raise(signum);
}int main()
{sigset_t set;sigset_t block;sigset_t oset;// 1.进行初始化sigemptyset(&set);sigemptyset(&block);sigemptyset(&oset);// 2.阻塞所有信号for (int i = 1; i <= 31; i++){sigaddset(&block, i);}sigprocmask(SIG_SETMASK, &block, &oset);// 3.循环打印未决信号集int count = 1;while (1){// 3.1 获取当前的未决信号集sigpending(&set);ShowSet(set);SendSig(count++);sleep(1);}return 0;
}

在这里插入图片描述
我们看到这样的情况,可以得出看出9号信号和19号信号是不可屏蔽的!

所以这里的结论就是如果我们将一个死循环进程的所有信号都屏蔽,该进程仍然可以通过9号信号退出。


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

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

相关文章

VS统计代码行数

1.使用查找和替换方式 按CTRLSHIFTF (Find in files)&#xff0c;勾上支持正则表达式&#xff0c; 然后输入搜索内容&#xff1a;^:b*[^:b#/].*$ 如图所示&#xff1a; 2.查看查询结果 需要注意&#xff1a;#开头和/开头或者空行都不计入代码量。

【研发日记】Matlab/Simulink技能解锁(二)——在Function编辑窗口Debug

目录 前言 行断点 条件断点 前言 见《【研发日记】Matlab/Simulink技能解锁(一)——在Simulink编辑窗口Debug》 行断点 当Matlab Function出现异常时&#xff0c;如果能确定大致的代码段&#xff0c;就可以在相应的行上设置一个断点&#xff08;Breakpoint&#xff09;&…

vs2022 qt 关于lnk2001和2019同时报错的问题

需要像qt中添加模块&#xff0c;这里&#xff0c;缺少qtopenglwidgets模块

大数据分析课----实时更新

1&#xff1a;Anaconda3 windows 安装 &#xff1a; 去官网下载&#xff1b; 然后安装好直接点next 点 i agree&#xff1b; 自己的电脑选第一个&#xff1b;学校的话选All Users &#xff1b; 选择自己存放的目录&#xff1b; 选前三个&#xff1b; 安装即可&#xff1b; 一直…

解决Maven项目中的依赖冲突

1. 排查依赖冲突 在IDEA中下载插件 Maven Helper用于排查依赖版本冲突。 打开项目的pom.xml文件&#xff0c;点击下方的【Dependency Analyzer】按钮切换到依赖解析页面。 2. 解决版本依赖 在依赖解析页面进行依赖冲突排查操作&#xff1a; 点击 【Exclude】 后会在爆红处所对…

为PDF创建目录(侧边栏目录)

通过可以新建书签的pdf阅读器。 知云翻译&#xff1a;可以新建书签和子书签。 Adobe Acrobat&#xff1a;只能新建书签&#xff0c;不能建立子书签。

《操作系统原理》算法总结

一、进程调度算法 先来先服务调度算法&#xff08;FCFS&#xff09; 每次调度是从就绪队列中&#xff0c;选择一个最先进入就绪队列的进程&#xff0c;把处理器分配给该进程&#xff0c;使之得到执行。该进程一旦占有了处理器&#xff0c;它就一直运行下去&#xff0c;直到该…

String 类 经典例题题集

一、把字符串转换成整数 (atoi) 请你来实现一个 myAtoi(string s) 函数&#xff0c;使其能将字符串转换成一个 32 位有符号整数&#xff08;类似 C/C 中的 atoi 函数&#xff09;。 函数 myAtoi(string s) 的算法如下&#xff1a; 读入字符串并丢弃无用的前导空格检查下一个字符…

中国企业走向世界,新加坡共和理工学院师生首站到访开源网安交流

近年来&#xff0c;中国企业在众多领域突飞猛进&#xff0c;不断追赶国际头部企业技术水平&#xff0c;甚至在某些领域已经达到国际领先水平&#xff0c;国内企业的最佳实践逐渐成为了全球精英学习研究的对象。 3月4日&#xff0c;由新加坡五所国立理工学院之一的新加坡共和理工…

金三银四刷完这个笔记,17K不能再少了....

大家好&#xff0c;最近有不少小伙伴在后台留言&#xff0c;得准备面试了&#xff0c;又不知道从何下手&#xff01;为了帮大家节约时间&#xff0c;特意准备了一份面试相关的资料&#xff0c;内容非常的全面&#xff0c;真的可以好好补一补&#xff0c;希望大家在都能拿到理想…

【HTML】day01

列表 作用&#xff1a;布局内容排序整齐的区域。 列表分类&#xff1a;无序列表、有序链表、定义列表 无序列表 <ul><li>test</li><li>test</li><li>test</li><li><h1>h1</h1></li></ul><!DOCTYPE…

216.组合总和|||

// 定义一个名为Solution的类 class Solution {// 初始化一个用于存储结果的列表&#xff0c;其中每个元素是一个整数列表&#xff0c;表示一组组合List<List<Integer>> result new ArrayList<>();// 初始化一个LinkedList用于存储当前路径上的整数LinkedLi…

Linux 驱动 中断(一)

中断是指计算机运行过程中&#xff0c;出现某些意外情况需主机干预时&#xff0c;机器能自动停止正在运行的程序并转入处理新情况的程序&#xff0c;处理完毕后又返回原被暂停的程序继续运行。 在 Linux 中&#xff0c;中断处理是操作系统与硬件设备之间通信的重要方式之一。Li…

边缘计算网关在机床生产中的应用-天拓四方

随着工业4.0的推进&#xff0c;物联网&#xff08;IoT&#xff09;技术在各个工业领域中的应用日益广泛。特别是在机床行业&#xff0c;物联网技术的引入不仅提高了生产效率&#xff0c;还实现了对机床设备的实时监控和远程维护。在这一背景下&#xff0c;边缘计算网关的角色愈…

android开发实例,retrofit解析

面试官的问题&#xff1a; &#xff08;1&#xff09;问&#xff1a;点击一个图标到这个应用启动的全过程&#xff08;前面是项目经验没啥好说的&#xff09;。 答&#xff1a;点击图标后通过startActivity远程调用到ams中&#xff0c;ams中将新启动的activity以activityrecor…

2024新版SonarQube+JenKins+Github联动代码扫描(2)-SonarQube代码扫描

文章目录 前言一、docker方式安装sonar二、启动容器三、创建数据库四、启动sonarqube五、访问sonar六、如果访问报错-通过sonar日志定位问题七、修改密码八、汉化&#xff08;看个人选择&#xff09;九、扫描十、我遇到的Sonar报错以及解决办法 总结 前言 这是2024新版SonarQu…

Python算法题集_分割回文串

Python算法题集_分割回文串 题131&#xff1a;分割回文串1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【参数回退回溯单行回文检测】2) 改进版一【参数回退回溯lambda回文检测】3) 改进版二【参数回退回溯函数回文检测】4) 改进版三【堆栈回退…

Python - getpass

文章目录 关于 getpass基本使用语法说明其它 关于 getpass getpass 是 Python 自带标准库 Python 官方文档 - getpass https://docs.python.org/3/library/getpass.html 基本使用 我们在看视频教程中&#xff0c;老师如果不想在代码中暴露 token、密码之类的信息&#xff0c…

Leet code 611 有效三角形个数

简单有效的思路&#xff1a;双指针解法 比如给出一个nums{4&#xff0c;3&#xff0c;2&#xff0c;4&#xff0c;5&#xff0c;6&#xff0c;8&#xff0c;10} 先将nums排序 -> { 2, 3, 4, 4, 5, 6, 8, 10} for(int inums.size()-1;i>2;i--) i的下标为当前最大值的下…

【C++】继续学习 string类 吧

开始使用 string类 吧 1 继续学习1.1 扩容机制1.2 string类对象的访问及遍历操作1.3 string类对象的修改操作1.4 其他一些成员函数 2 实践解决问题&#xff1a;Thanks♪(&#xff65;ω&#xff65;)&#xff89;谢谢阅读&#xff01;&#xff01;&#xff01;下一篇文章见&…