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模型下使用。 导入…

【C++】每日一题 114 二叉树展开为链表

给你二叉树的根结点 root &#xff0c;请你将它展开为一个单链表&#xff1a; 展开后的单链表应该同样使用 TreeNode &#xff0c;其中 right 子指针指向链表中下一个结点&#xff0c;而左子指针始终为 null 。 展开后的单链表应该与二叉树 先序遍历 顺序相同。 #include <…

QT设计模式:适配器模式

基本概念 适配器模式&#xff08;Adapter Pattern&#xff09;是一种结构型设计模式&#xff0c;允许将一个类的接口转换成客户端所期望的另一个接口&#xff0c;可以让原本由于接口不兼容而不能一起工作的类能够一起工作。 适配器模式需要实现的部分为&#xff1a; Target类…

MACHENIKE M7 无线鼠标快捷键

MACHENIKE M7 无线鼠标快捷键 前后灯 颜色&#xff1a;红-紫-蓝&#xff08;默认值&#xff09;-绿-青-黄-粉 操作&#xff1a;同时按下鼠标左键右键 呼吸灯 模式&#xff1a;单色常亮、单色呼吸、七彩呼吸 操作&#xff1a;同时按下鼠标左键右键中键

Spring IoCDI—DI详解

在Spring框架中&#xff0c;依赖注入&#xff08;Dependency Injection&#xff0c;DI&#xff09;是一种重要的设计模式&#xff0c;它通过将对象的依赖关系从代码中硬编码移动到配置文件中&#xff0c;从而实现了松耦合、易于维护和测试的代码。下面我将详细介绍Spring中的依…

【栈】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中…

【OTS4WORD】“精简并行过程”——容易剪裁的“软件过程改进方法和规范”模板

附件资源是作者针对SPP采用模板重新格式化打包制作&#xff0c;原模板具有格式不受控的缺点&#xff0c;导致文档编制过程中引起不必要的排版麻烦。 附件资源适用于希望改进工作流程&#xff0c;适配CMMI质量管理体系的公司或个人使用&#xff0c;质量改进管理组织、项目管理组…

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拥有许…