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;#开头和/开头或者空行都不计入代码量。

实名认证实现很难?Java实名认证三要素+人像接口代码

大数据时代&#xff0c;是否还在为用户信息的真实性头疼不已&#xff1f;是否还在担心业务中出现冒名顶替的风险&#xff1f;是否还在为实现线上平台实名制而发愁&#xff1f;今天小编为您带来了实时联网、便于集成、快速核验的翔云身份证三要素人像实名认证接口集成方式与代码…

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

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

算法D34 | 贪心算法4 | 860.柠檬水找零 406.根据身高重建队列 452. 用最少数量的箭引爆气球

860.柠檬水找零 本题看上好像挺难&#xff0c;其实挺简单的&#xff0c;大家先尝试自己做一做。代码随想录 分5/10/20讨论找零方案即可。 Python: class Solution:def lemonadeChange(self, bills: List[int]) -> bool:ch5 0ch10 0for b in bills:if b 20:ch5 - 1if ch1…

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】 后会在爆红处所对…

当Linux 磁盘满了,查看大文件并删除

当你的Linux磁盘空间满了时&#xff0c;可以通过以下步骤查找大文件并删除它们&#xff1a; 检查磁盘空间&#xff1a; 使用以下命令检查磁盘空间的使用情况&#xff1a; df -h这将显示文件系统的使用情况&#xff0c;包括每个文件系统的总大小、已用空间、可用空间和挂载点。 …

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

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

Java通过反射给注解赋值

在用java导出Excel的时候&#xff0c;表头不能写死&#xff0c;而是根据情况变化的。 实体类如下&#xff1a; public class EquSysExportNoChainVo {Excel(name "")private String thisValue; //当前值 } 给实体类的Excel的name赋值的方法如下&…

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

一、进程调度算法 先来先服务调度算法&#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;由新加坡五所国立理工学院之一的新加坡共和理工…

Docker 干货系列 (持续更新)

dive 直接用本地镜像名称来启动&#xff0c;不需要走 hub dive.sh IMAGE_NAME"${1}" TMP_FILE/tmp/dive-tmp-image.tar docker save "$IMAGE_NAME" > $TMP_FILE && dive $TMP_FILE --sourcedocker-archive && rm $TMP_FILE示例&#…

Pytorch_1_基本语法

一、Pytorch的基本元素操作 1.引入torch from __future__ import print_function import torch 2.创建矩阵 x torch.empty(5,3) print(x) 3.输出结果&#xff1a; tensor([[7.9191e34, 1.1259e24, 1.2359e-42], [4.0824e-40, 1.1379e-35, 2.5353e30], [8.…

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

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

数学分析(单多变量微积分)复习和学习大纲

前言&#xff1a;开始整理这些资料的时候&#xff0c;已经是本人研一下学期的开学了。然而在遥远的4年前本人因为疫情的原因居家学习的时候&#xff0c;数学分析一度是我的噩梦。但时至今日&#xff0c;越来越发现这些基础的数学问题的重要性。尽管本人就读的本科一再强调其学生…

【HTML】day01

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

GDOI2024 游记

推荐在 cnblogs 上阅读。 GDOI2024 游记 Day -6 元宵节&#xff0c;得知自己可以参加 GDOI&#xff0c;惊喜坏了。 要知道&#xff0c;我 CSP-S 2&#xff0c;NOIP 没参加。居然去了 GDOI&#xff01; 真的有很多很多想说的话&#xff0c;非常非常感谢教练。但是这里不作抒…

稀碎从零算法笔记Day7-LeetCode:买卖股票的最佳时机

题型&#xff1a;数组、动态规划 链接&#xff1a;121. 买卖股票的最佳时机 - 力扣&#xff08;LeetCode&#xff09; 来源&#xff1a;LeetCode 题目描述 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天…