【Linux】阻塞信号|信号原理

news2024/9/23 18:24:18

常见的信号术语

信号递达(Delivery):

  • 信号实际被执行处理的过程;(当一个信号被递达给进程时,该信号的处理动作已经开始执行实际执行信号的处理动作

信号未决(Pending):

  • 信号从产生到递达的中间状态;信号已经生成但尚未被递达的状态。在此期间,信号处于阻塞状态,直到它被递达给目标进程

信号阻塞(Block):

  • 进程可以选择阻塞某个信号;(即使信号已经生成,也会保持在未决状态,不会被递达给进程。信号只有在解除阻塞后才能被递达

信号忽略:

  • 信号被递达后,进程选择不做任何响应。不同于信号阻塞,被忽略的信号已经完成了递达,只是进程对其没有任何反应

捕获信号:

  • 进程通过自定义信号处理程序来处理信号,而不是使用系统的默认动作;

信号在内核中的表示 

在上篇中介绍了信号是由位图保存的,信号如何产生的;

信号是用户,操作系统,进程交互用的;而进程是如何知道操作系统给它发了信号呢;

信号标志位 

  • 阻塞 (block):如果设置,该信号会阻塞,不会被递达给进程;
  • 未决 (pending):如果设置,表示该信号已生成但未处理;

信号通过三种结构来表示和管理,这些结构存储在进程的task_struct中;

  • Pending 位图:表示哪些信号已经生成但尚未被递达或处理;(跟踪信号的未决状态)
  • Block 位图:记录了哪些信号被当前进程所阻塞。控制信号是否可以被递达;
  • Handler 函数指针:指向一个函数指针,用于指定当信号递达时要执行的处理动作;

Pending表 

  • 在信号位图(Signal Bitmap)中,每个比特位的位置表示某个信号,比特位的内容代表是否收到该信号(信号是否未决);如果有信号发送给该进程,那么这个位图对应的信号位会置为1,没有就是0;
  • 假如给进程发送2号信号,那么该位图的第3位会置位1,但不会立即处理该信号,会在合适的时候处理,这个合适的时候是进程从内核态返回到用户态的时候进行处理
  • Pending表的存在让进程知道接受了哪些信号并准备处理信号;而信号是否要被处理,还要查看该信号是否被阻塞,此时需要查看进程中Block表的内容;

Block表 

进程用一张位图表来表示被进程阻塞的信号集;每个比特位的位置代表着某个信号编号,比特位的内容代表着该信号是否被阻塞;内容为1表示对该信号进行阻塞,为0表示没有对该信号进行阻塞。第一个比特位位置代表 1号信号,以此类推(位图结构)

有了上面两张位图表,进程就能知道接受了哪些信号,信号是否阻塞(不需要处理),而信号也有需要处理的;这个就要看handler表;

handler表

进程中这张handler表与上面两张位图表有所不同,这是函数指针数组(sighandler_t handler[32]);数组的下标是信号的编号,数组的内容是函数指针(该信号的处理函数);处理函数(处理动作)包括默认,忽略以及自定义;

  • 每个信号都有两个标志位分别表示阻塞(block)和未决(pending),还有一个函数指针表示处理动作。
  • block、pending和handler这三张表的每一个位置是一一对应的;
  • 信号产生时,内核在进程控制块中设置该信号的未决标志,直到信号递达才清除该标志。在上图的例子中,1号信号SIGHUP 未阻塞也未产生过(pending位图对应信号位置标志位为0,block位图对应信号位置标志位为0),当它递达时执行默认处理动作(SIG_DFL)。
  • 对于2号信号SIGINT,该信号产生过(pending位图对应信号位置标志位为1,处于未决),但正在被阻塞(block位图对应信号位置标志位为1),所以暂时不能递达。虽然它的处理动作是忽略(SIG_IGN),但在没有解除阻塞之前不能忽略这个信号,因为进程仍有机会改变处理动作之后再解除阻塞。
  • 3号信号SIGQUIT 未产生过(pending位图对应信号位置标志位为0),该信号正在被阻塞(block位图对应信号位置标志位为1),一旦产生SIGQUIT信号将被阻塞,它的处理动作是用户自定义函数sighandler。

总结:

一个信号哪怕没有被产生,也不影响该信号被阻塞;

POSIX.1标准 

允许系统在信号解除阻塞之前,递送该信号一次或多次给进程。

如果在进程接触对某信号的阻塞之前,该信号产生过多次,该如何处理❓

常规信号(普通信号)

        如果一个常规信号在被解除阻塞之前产生了多次,那么仅会递送一次该信号给进程。

实时信号

        实时信号在被解除阻塞之前产生的多次可以被依次放入一个队列中等待递送。

sigset_t

 由于block和pending 位图是内核内部的数据结构,用户程序无法直接访问和修改它们,OS也不能提供十几个参数的函数给用户使用吧,所以就有了 sigset_t。为了能够修改这些信号集,用户程序需要通过系统调用来进行操作:sigset_t类型的数据结构让用户可以方便地设置和查询信号集的状态;

  • 在block,pending位图中,比特位非0即1,只表示信号是否产生;不记录产生了多少次;
  • 未决和阻塞标志可以用相同的数据类型 sigset_t 来存储(在用户层);sigset_t 称为信号集,这个类型可以表示每个信号的“有效”或“无效”状态。

在阻塞信号集中 :

“有效”状态表示信号被阻塞,“无效”状态表示信号未被阻塞。

在未决信号集
“有效”状态表示信号处于未决状态,“无效”状态表示信号没有被生成或已被处理。

信号集操作函数 

操作系统提供了一些函数来管理信号集(sigset_t,包括Block和pending表),以下是常见的信号集操作函数(都包含在signal.h头文件中):

sigemptyset

int sigemptyset(sigset_t *set);
  • 将set指向的信号集清空
  • 成功返回0,否则返回-1.

sigfillset

初始化一个满的信号集,跟sigemptyset函数相反,让信号集中每一个比特位都置为1。 

int sigfillset(sigset_t *set);
  • 将set指向的信号集填满
  • 成功返回0,否则-1.

sigaddset

从信号集中添加一个指定的信号。 

int sigaddset(sigset_t *set, int signum);
  • 给set指向的信号集中添加一个signum信号
  • 成功放回0,否则-1.

sigdelset

从信号集中删除一个指定的信号 

int sigdelset(sigset_t* set,int signum);
  • 从set指向的信号集中删除一个signum信号
  • 成功返回0,失败则返回-1.

sigismember 

检查一个指定的信号是否在信号集中

int sigismember(const sigset_t *set,int signum);
  • 如果set指向的信号集中有signum信号就返回1,不在返回0,查看失败返回-1。

sigprocmask

检查或者修改信号屏蔽字(阻塞信号集)。用来阻塞或者解阻信号。
跟上面的sigaddset和sigdelset函数不一样的是,sigprocmask可以修改进程的Block表。 

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

参数:

how:指定操作类型。以下是常见的操作类型:
        SIG_BLOCK:将set指向的信号集中的信号添加到阻塞信号集中
        SIG_UNBLOCK:从阻塞信号集中移除set指向的信号集中的信号
        SIG_SETMASK:将set指向的信号集设置为新的阻塞信号集
set:指向一个sigset_t类型的对象,用于修改阻塞信号集。如果该参数为NULL,则表示不修改阻塞信号集。
oldset:指向一个sigset_t类型的对象,用于存储被set修改之前的阻塞信号集。
成功返回0,失败返回-1.

 sigpending

获取当前进程的未决信号集(pending表)

int sigpending(sigset_t *set);
  • 将set指向的信号集重置为当前进程的未决信号集
  • 成功返回0,否则-1.

 信号集实验

实验步骤如下:

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

// 定义一个函数来打印信号集的内容
void PrintSet(sigset_t *set)
{
    // 循环遍历信号集中的每个信号位
    for (int i = 31; i >= 1; i--)  // 注意:这里从31开始到1结束是不正确的,因为SIGRTMIN是1, SIGRTMAX是64
    {
        // 如果信号集中的信号i被设置,则输出'1'
        if (sigismember(set, i)) 
        {
            putchar('1');
        }
        // 否则输出'0'
        else
        {
            putchar('0');
        }
    }
    // 输出换行符
    puts("");
}

int main()
{
    sigset_t s, p;

    // 初始化信号集s为空
    sigemptyset(&s); 

    // 将 SIGINT (通常为 2) 添加到信号集s中
    sigaddset(&s, SIGINT);

    // 设置信号屏蔽字,将信号集s中的信号设置为阻塞状态
    // 这意味着在此之后,SIGINT将不会被进程接收
    sigprocmask(SIG_BLOCK, &s, NULL);

    // 主循环
    while (1)
    {
        // 查询当前进程的未决信号集,并将其存储在p中
        sigpending(&p);

        // 打印未决信号集p的内容
        PrintSet(&p);

        // 让进程休眠一秒
        sleep(1);
    }

    return 0;
}

 按下ctrl+c后程序没有被终止,说明这个信号确实被阻塞了,然后未决表显示该信号一直出于未决状态,没有被递达 

 

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

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

相关文章

快速上手Spring Boot

快速上手Spring Boot (qq.com)

凡图公益行:以爱之名,凡图家庭教育专家入户指导,引领残疾儿童勇敢启航 !

凡图公益行&#xff1a;以爱之名&#xff0c;凡图家庭教育专家入户指导&#xff0c;引领残疾儿童勇敢启航 &#xff01; 在社会的各个角落&#xff0c;有一群特殊的孩子。 他们因身体的局限承受着常人难以想象的挑战。 这些挑战不仅体现在日常生活的琐碎之中&#xff0c;更深…

react使用Lodash 库实现根据数组内对象的某属性排序

一、描述 根据数组内的对象的某个属性进行排序操作是很常见的方法&#xff0c;但是如果自己写一个方法&#xff0c;有可能出现错误的情况&#xff0c;且耗费时间&#xff0c;这里介绍一个第三方的工具“Lodash ”库&#xff0c;用这个来实现根据数组内对象的某属性排序特别方法…

LVS原理详解及部署

目录 一、LVS原理 1.LVS简介 2.LVS结构 3.IP负载均衡技术 4.LVS相关术语 二、LVS负载均衡四种工作模式 1.LVS-DR模式 2.LVS-NAT模式 3.LVS-TUN模式&#xff08;了解&#xff09; 4.FULL-NAT模式&#xff08;了解&#xff09; 三、LVS负载均衡十种调度算法 四、LVS部…

Open3D 使用Jet颜色映射渲染点云

目录 一、概述 1.1Jet颜色映射的定义 1.2Jet颜色映射的应用 二、代码实现 2.1关键函数 2.2完整代码 三、实现效果 3.1原始点云 3.2渲染后点云 Open3D点云算法汇总及实战案例汇总的目录地址&#xff1a; Open3D点云算法与点云深度学习案例汇总&#xff08;长期更新&am…

书生大模型实战营闯关记录----第六关:大语言模型微调实战,LoRA和QLoRA微调,理论+Xtuner微调实操

文章目录 大语言模型微调基础1 基本概念1.1 Finetune简介1.1.1 Finetune的两种范式 1.2 微调技术1.2.1 LoRA简介1.2.2 QLoRA简介 1 微调前置基础2 准备工作2.2 创建虚拟环境2.3 安装 XTuner2.4 模型准备 3 快速开始3.1 微调前的模型对话3.2 指令跟随微调3.2.1 准数据文件3.2.2 …

ELK架构介绍

一、ELK简介 ELK 是由三个开源软件组成的&#xff0c;分别是&#xff1a;Elasticsearch、Logstash和Kibana&#xff0c;这三个软件各自在日志管理和数据分析领域发挥着重要作用。Elasticsearch提供分布式存储和搜索能力&#xff1b;Logstash负责数据收集和处理&#xff0c;而K…

如何简单粗暴的下载m3u8视频并转换为mp4格式

m3u8文件介绍 M3U&#xff08;Moving Picture Experts Group Audio Layer 3 Uniform Resource Locator&#xff09;这种文件格式是音视频文件的列表文件&#xff0c;是纯文本文件。你下载下来打开它&#xff0c;播放软件并不是播放它&#xff0c;而是根据它的记录找到网络地址…

react+taro的文字粘贴识别功能

效果图 <View className"components-page"><Textareastyle"font-size:12PX"className"textareaStyle"placeholderClass"placeholderStyle"placeholder"例&#xff1a;公司&#xff1a;xxxx公司, 电话:13*********, 地址…

MybatisPlus——service批量新增

Service接口 批量新增 批量插入10万条用户数据&#xff0c;并作出对比&#xff1a; 普通for循环插入IService的批量插入 Test void testSaveOneByOne() {long b System.currentTimeMillis();for (int i 1; i < 100000; i) {userService.save(buildUser(i));}long e Sy…

leetcode递归(LCR 024. 反转链表)

前言 经过前期的基础训练以及部分实战练习&#xff0c;粗略掌握了各种题型的解题思路。现阶段开始专项练习。 描述 给定单链表的头节点 head &#xff0c;请反转链表&#xff0c;并返回反转后的链表的头节点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&am…

2024年6月scratch图形化编程等级考试四级真题

202406 青少年软件编程等级考试Scratch四级真题 试卷总分数&#xff1a;100分 考试时长&#xff1a;60 分钟 第 1 题 运行下列程序&#xff0c;输入单词“PLAY”&#xff0c;最后角色说&#xff1f;&#xff08; &#xff09; A&#xff1a;LY4AP B&#xff1a;AP4LY C&am…

【Linux】【git】创建使用+分支管理+场景模拟

文章目录 引子1. 创建 提交 删除init - - 创建一个初始化的本地仓库config - - 对本地仓库的配置add - - 新增commit - - 提交rm - - 删除 2. 状态查看 和 版本回退log - - 日志status - - 查看diff - - 比较reset - - 版本回退场景模拟1_1 reflog - - 参考日志场景模拟1_2 3. …

K短路(A*算法)

K短路&#xff1a; 在图论中&#xff0c;K短路问题是指在一个图中找到从起点s到终点t的第K短的路径。其中&#xff0c;第1短路径即为最短路径。K短路算法在实际应用中有着广泛的用途&#xff0c;如在通信网络中找到替代的最短路径等。 基本概念 K短路&#xff1a;从起点s到终…

美国服务器稳定么?影响服务器稳定性的6个因素

美国服务器稳定么&#xff1f;美国服务器的稳定性是相当不错的&#xff0c;这主要得益于其先进的技术、成熟的基础设施以及严格的管理措施。美国拥有众多知名的服务器提供商&#xff0c;这些提供商通常会采用顶级的硬件设施&#xff0c;如英特尔、AMD等知名品牌的处理器&#x…

Chromium编译指南2024 - Android篇:前置要求(一)

1.引言 欢迎阅读《Chromium编译指南2024 - Android篇》。本指南旨在帮助开发者理解和掌握在Android平台上编译Chromium的全过程。Chromium是一个开源的浏览器项目&#xff0c;由Google主导开发&#xff0c;并为多个现代浏览器提供基础代码。Android作为全球使用最广泛的移动操…

DirectX_web_setup.exe

F:\Downloads\录屏软件\OBS DirectX_web_setup.exe

IP实现https访问的简易方式

很多项目怕麻烦不愿意申请域名&#xff0c;也不想备案&#xff0c;所以直接用服务器IP地址做WEB项目更快一些&#xff0c;但又想给IP地址申请SSL证书&#xff0c;这种情况下需要用到IP类型的专用SSL证书。 IP SSL证书是支持IP地址实现HTTPS加密的SSL证书&#xff0c;为不能提供…

Linux服务管理(五)Apache服务优化

CustomLog "|/bin/rotatelogs -l /wwwlogs/access_%Y%m%d.log 86400" combined日志旋转可参考这篇文章&#xff1a; https://blog.csdn.net/weixin_43576565/article/details/139989701 要优化首先你得有Apache yum -y install httpd启动 service httpd start写入…

[Qt][按钮类控件]详细讲解

目录 0.按钮状态说明1.Push Button2.Radio Button3.Check Box4.Tool Button 0.按钮状态说明 clicked&#xff1a;⼀次 ⿏标按下⿏标释放 触发pressed&#xff1a;鼠标按下时触发released&#xff1a;鼠标释放时触发toggled&#xff1a;checked属性改变时触发 1.Push Button QP…