Linux-信号保存

1. 概念

        进程执行信号的处理动作,称为 信号递达(Delivery)

        信号从产生到递达之间的状态,称为 信号未决(Pending)

        进程可以选择 阻塞(Block)某个信号

过程:

        信号产生 —— 信号未决 —— (是否阻塞)—— 信号递达

        信号在未决状态,其实就是信号保存在进程PCB内

阻塞和忽略的区别:

        忽略是一种信号的处理动作,在信号递达时才会体现;而阻塞,信号根本就不会递达

        那么信号是如何保存在进程PCB(task_struct)中的呢? 

2. 内核结构

        内核中task_struct的会有三个指针指向三个位图

         由pending位图决定信号是否产生,被保存;block位图决定信号是否被阻塞,handler位图决定信号被抵达时的处理动作

        其中__sighandler_t类型是函数指针,void handler(int ),函数参数为int类型,返回值为void类型,其中SIG_DEF(默认)和SIG_IGN(忽略)是宏定义,分别表示__sighandler_t类型强转的0和1

        当信号的默认处理动作为默认时,它会去调用对应的信号默认处理动作

信号处理流程:

        

3. 函数接口

        默认情况下,阻塞block位图为全0,用户可以修改

        OS提供自定义类型 sigset_t 和对应的操作该位图的方法,用户需要用这些方法和接口才能修改 sigset_t 类型的位图。用户想要修改block阻塞位图就必须利用 sigset_t 作为系统调用接口的参数。

        sigset_t 被称为 信号集;block位图,被称为 阻塞信号集 或者 信号屏蔽字(signal mask)

修改信号集的接口

  • sigemptyset:初始化set所指向的信号集,使其中所有信号的对应bit清零,表示该信号集不包含任何有效信号
  •  函数sigfillset初始化set所指向的信号集,使其中所有信号的对应bit置位,表示该信号集的有效信号包括系统支持的所有信号
  • 初始化sigset_t变量之后就可以在调用sigaddset和sigdelset在该信号集中添加或删除某种有效信号
  • sigismember:确定 signum 信号对应的位置是否为1 返回值:真1,否0,出错-1

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

读取或更改进程的信号屏蔽字:

set:

        若set为空指针,读取进程当前的信号屏蔽字,oldset传出

        若set为非空,根据how指示,通过set修改信号屏蔽字,原先的通过oldset(若为非空)传出

how:

SIG_BLOCKmask = mask | set添加
SIG_UNBLOCKmask = mask & ~set解除
SIG_SETMASKmask = mask覆盖
        如果调用sigprocmask解除了对当前若干个未决信号的阻塞,则在函数返回前,至少将其中一个信号递达(在下一篇博客中解答为什么)

读取当前进程的未决信号集:

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

通过这些接口做的小实验:

#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <assert.h>
using namespace std;void handler(int sig)
{cout << "捕获signal:" << sig << endl;
}void Print(const sigset_t& set)
{for(int i = 1; i <= 31; ++i){if(sigismember(&set, i) == 1)cout << 1;else    cout << 0;}cout << endl;  
}int main()
{for(int i = 1; i <= 31; ++i){signal(i, handler);}sigset_t set;sigfillset(&set);sigprocmask(SIG_SETMASK, &set, nullptr);while(true){sigset_t oset;sigemptyset(&oset);sigpending(&oset);Print(oset);sleep(1);}return 0;
}
i=1
id=$(pidof mysignal)
while [ $i -le 31 ]
doif [ $i -eq 9 ];thenlet i++continuefiif [ $i -eq 19 ];thenlet i++continuefikill -$i $idecho "kill -$i $id"let i++sleep 1
done

完。 

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

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

相关文章

linux上go项目打包与部署

1.第一步把项目打包 1.确保本地goland的操作系统为linux go env找到GOOS如果为window就修改为Linux 修改命令为 go env -w GOOSlinux2.打包 在项目根目录下输入 go build main.go然后项目根目录下会出现一个mian的二进制文件 3.上传包 将 main 程序包放到服务的目录下&…

鸿蒙开发接口Ability框架:【 (ServiceExtensionAbility)】

ServiceExtensionAbility ServiceExtensionAbility模块提供ServiceExtension服务扩展相关接口的能力。 说明&#xff1a; 本模块首批接口从API version 9开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 本模块接口仅可在Stage模型下使用。 导入…

【栈】Leetcode 1047. 删除字符串中的所有相邻重复项

题目讲解 1047. 删除字符串中的所有相邻重复项 算法讲解 使用栈这个数据结构&#xff0c;每一次入栈的时候观察此时的字符和当前栈顶字符是否相等&#xff0c;如相等&#xff1a;栈顶出栈&#xff1b;不相等&#xff1a;入栈 class Solution { public:string removeDuplica…

Linux-进程管理类命令实训

实训1&#xff1a;进程查看&#xff0c;终止&#xff0c;挂起及暂停等操作 1.使用ps命令显示所有用户的进程 2.在后台使用cat命令。查看进程cat&#xff0c;并杀死进程 3.使用top命令只显示某一用户的进程。 4.执行命令cat&#xff0c;把Ctrlz挂起进程&#xff0c;输入jobs命令…

「网络流 24 题」最小路径覆盖 【最小路径覆盖】

「网络流 24 题」最小路径覆盖 思路 具体可以看 这篇博客 对于有向无环图&#xff0c;我们只需要将假装将点裂成左点和右点&#xff08;实际没有裂开&#xff09;&#xff0c;然后连边&#xff1b; 在上面跑二分图最大匹配后&#xff0c;剩下没有匹配的左点就是终点&#xff…

python与java用途区别有哪些

区别&#xff1a; 1.Python比Java简单&#xff0c;学习成本低&#xff0c;开发效率高。 2.Java运行效率高于Python&#xff0c;尤其是纯Python开发的程序&#xff0c;效率极低。 3.Java相关资料多&#xff0c;尤其是中文资料。 4.Java版本比较稳定&#xff0c;Python2和3不…

【第14章】spring-mvc之ajax

文章目录 前言一、准备二、单个值1.前端2.后端3. 结果 三、对象1.前端2.后端3. 结果 四、JSON对象1.前端2.后端3. 结果 五、JSON数组1.前端2.后端3. 结果 总结 前言 AJAX&#xff08;Asynchronous JavaScript and XML&#xff09;是一种用于创建快速动态网页的技术&#xff0c…

学习和“劳动”相关的谚语,柯桥俄语培训

1. Бог труды́ лю́бит. 天道酬勤。 2. В ми́ре нет тру́дных дел, ну́жно лишь усе́рдие. 世上无难事,只怕有心人。 3. У́тро вечера мудренее. 一日之计在于晨。 4. Что посе́ешь,…

cesium 雷达遮罩(电弧球效果)

cesium 雷达遮罩(电弧球效果) 以下为源码直接复制可用 1、实现思路 通过修改“material”材质来实现轨迹球效果 2、代码示例 2.1 index.html <!DOCTYPE html> <html lang="en"><head><!

【初阶数据结构】栈

目录 栈的概念及结构栈的实现栈的结构栈的初始化栈的销毁入栈出栈取栈顶元素判断栈是否为空取栈中元素个数代码测试 完整代码Stack.hStack.ctest.c 栈的概念及结构 栈&#xff1a;是一种特殊的线性表&#xff0c;它只允许在固定的一端进行插入和删除元素的操作。   栈顶&…

[MDK] 介绍STM32使用C和C++混合编程的方法

目录 [MDK] 介绍STM32使用C和C混合编程的方法前言业务场景步骤1基础工程步骤2写代码步骤3添加cpp文件步骤4配置与编译上机现象后记 [MDK] 介绍STM32使用C和C混合编程的方法 前言 搞单片机编程大多数还是使用MDK编程&#xff0c;自己对MDK这个软件也比较熟悉&#xff0c;在网络…

【通信】电子科协通信专题

数字通信 最直观的通信方式-基带通信 问题&#xff1a;①无限大的带宽②天线体积

java回调机制

目录 一、简介二、示例2.1 同步回调2.2 异步回调2.3 二者区别 三、应用场景 一、简介 在Java中&#xff0c;回调是一种常见的编程模式&#xff0c;它允许一个对象将某个方法作为参数传递给另一个对象&#xff0c;以便在适当的时候调用该方法。 以类A调用类B方法为例: 在类A中…

KMP + Compose 跨平台 Android IOS 实战入门

KMP&#xff08;Kotlin Multiplatform&#xff09;是一种面向移动端开发的跨平台框架&#xff0c;使用 Kotlin 语言编写&#xff0c;可实现在 Android 和 iOS 平台上共享代码和逻辑。通过 KMP 框架&#xff0c;我们可以编写一次代码&#xff0c;然后在不同的平台上进行部署和运…

python能够干什么?

python有哪些用途&#xff1f; Python是一种高级编程语言&#xff0c;它被广泛用于各种不同的领域。以下是Python的一些常见用途&#xff1a; 网络应用开发&#xff1a;Python可以用于编写Web应用程序、API、爬虫、网络服务器等。数据科学和机器学习&#xff1a;Python拥有许…

深究muduo网络库的Buffer类!!!

最近在学习了muduo库的Buffer类&#xff0c;因为这个编程思想&#xff0c;今后在各个需要缓冲区的项目编程中都可以用到&#xff0c;所以今天来总结一下&#xff01; Buffer的数据结构 muduo的Buffer的定义如下&#xff0c;其内部是 一个 std::vector&#xff0c;且还存在两个…

Shell编程之条件语句

条件测试 文件测试与整数测试 字符串测试与逻辑测试 if语句 if单分支语句 if双分支语句 if多分支语句 case分支语句 条件测试操作 条件测试操作 1 条件判断 test命令测试表达式是否成立&#xff0c;若成立返回0.否则返回其它数值。 格式 1 test 条件表达式 格式 2 …

【Redis7】了解Redis

1.常见数据库 1.1.键值存储数据库 如 Map 一样的key-value 对&#xff0c;典型代表就是 Redis。 1.2.列存储数据库 关系型数据库是典型的行存储数据库&#xff0c;按行存储的数据在物理层面占用的是连续存储空间&#xff0c;不适合海量数据存储。而按列存储则可实现分布式存储&…

猫不爱喝水是正常的?求求別再被洗脑了!日常可以补水的主食分享

猫不爱喝水正常吗&#xff1f;看给猫喂的什么&#xff0c;喂的罐头的话不爱喝水问题不大。喂的干粮猫还长期不喝水&#xff0c;处于缺水状态&#xff0c;可能会出现便秘、上火、尿黄、尿少等症状。在高温的夏季&#xff0c;猫还可能因脱水而中暑&#xff0c;严重时甚至可能导致…

用c++实现汉诺塔问题、归并排序

6.1.3 汉诺塔问题 【问题】 汉诺塔问题(Hanio tower problem)来自一个古老的传说&#xff1a;有一座宝塔&#xff08;塔A),其上有64个金碟&#xff0c;所有碟子按从大到小由塔底堆放至塔顶。紧挨着这座宝塔有另外两座宝塔&#xff08;塔B和塔C),要求把塔A上的碟子移动到塔C上…