Linux:进程通信(二)信号的保存

目录

一、信号的处理是否是立即处理的?

 二、信号如何保存

1、阻塞、未决、递达

2、信号集

3、信号集操作函数

4、sigprocmask函数

5、sigpending 函数


上篇文章我们讲解了信号的产生:Linux:进程信号(一)信号的产生

接下来我们来看一下信号的保存

一、信号的处理是否是立即处理的?

        信号的处理是否立即进行,取决于信号的类型、进程的当前状态,以及进程对信号的处理策略。

  1. 信号的优先级:某些信号需要立即处理,比如 SIGKILL(强制终止进程)和 SIGSTOP(暂停进程)。这些信号一旦被发送给目标进程,操作系统会立即采取行动。其他信号,比如 SIGTERMSIGUSR1,可能会被延迟处理,特别是在进程有更高优先级的任务在进行时。

  2. 进程的状态:如果进程正在内核态(如系统调用期间),信号的处理可能被延迟,直到进程回到用户态。此外,如果进程正在被其他信号阻塞,或处于某种临界区,信号也可能被暂时推迟。

  3. 信号的阻塞和掩码:进程可以通过信号掩码来阻止某些信号的立即处理。操作系统将这些阻塞的信号放入进程的信号队列中,直到进程解除阻塞。

  4. 信号处理函数:进程可以设置信号处理函数。当信号到达时,如果进程当前正在运行中,它可能会等到适当的时机(如下一个调度周期)才调用信号处理函数。

 二、信号如何保存

信号需要被进程记录下来,以确保即使在信号到达时进程无法立即处理时,信号也不会丢失。这种记录通常发生在进程的信号队列中。

信号队列是内核为每个进程维护的一个数据结构,用于存储已经到达但尚未被处理的信号。当进程接收到信号时,内核将信号放入进程的信号队列中,然后等待进程在适当的时机处理它们。这样做可以确保即使进程在信号到达时处于某种阻塞状态,也能够在稍后的时候处理这些信号。

信号队列通常存储在内核的内存中,并且对于每个进程都有一个单独的信号队列。进程可以使用系统调用来检查它的信号队列,并且可以对信号队列进行操作,比如阻塞或解除阻塞某些信号。

1、阻塞、未决、递达

实际执行信号的处理动作称为信号递达(Delivery)
信号从产生到递达之间的状态,称为信号未决(Pending)
进程可以选择阻塞 (Block ) 某个信号。
被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作.
注意 , 阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后可选的一种处理动作。

 如下图所示

比特位的位置表示信号的编号,比如图中是三号信号,三号信号产生后,未决信号集对应位置为1,内核来判断是否应该被处理,如果被处理则置为0 。而如果该信号被阻塞,那么就不会被处理,直到阻塞解除。

那么信号集如何管理呢:

2、信号集

sigset_t

sigset_t 用于表示一组信号,通常用于表示被阻塞的信号集合或者待处理的信号集合。

在内部实现上,sigset_t 可以被看作是一个位图,其中每个位代表一个信号。如果某个位被设置为 1,则表示对应的信号被包含在集合中;如果被设置为 0,则表示对应的信号不在集合中。

这种位图的表示方式非常高效,因为它可以用很小的内存空间表示很多信号。通常情况下,sigset_t 的大小被限制在一个字(通常是 32 位或 64 位)的大小范围内,所以它适用于表示系统支持的信号数量。

sigset_t可以本质上被视为一个位图 ,关于位图我们前面也介绍过:C++:Hash应用【位图与布隆过滤器】

3、信号集操作函数

sigset_t 类型对于每种信号用一个 bit 表示 有效 无效 状态 , 至于这个类型内部如何存储这些 bit 则依赖于系统实现, 从使用者的角度是不必关心的 , 使用者只能调用以下函数来操作 sigset_ t 变量
#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);
  • sigemptyset(sigset_t *set): 此函数用于将信号集合 set 清空,即将所有信号从集合中移除,使得 set 表示一个空集。调用此函数后,set 中不包含任何信号。

  • sigfillset(sigset_t *set): 此函数用于将信号集合 set 填满,即将所有信号添加到集合中,使得 set 包含系统支持的所有信号。调用此函数后,set 中包含所有可能的信号。

  • sigaddset(sigset_t *set, int signo): 此函数用于向信号集合 set 中添加指定的信号 signo。添加成功后,set 中将包含 signo 代表的信号。

  • sigdelset(sigset_t *set, int signo): 此函数用于从信号集合 set 中删除指定的信号 signo。删除成功后,set 中将不再包含 signo 代表的信号。

  • sigismember(const sigset_t *set, int signo): 此函数用于检查指定的信号 signo 是否包含在信号集合 set 中。如果 signo 存在于 set 中,则返回非零值;否则返回 0。

需要注意的是在使用 sigset_ t 类型的变量之前 , 一定要调 用 sigemptyset sigfillset 做初始化 , 使信号集处于确定的状态。初始化sigset_t 变量之后就可以在调用 sigaddset sigdelset 在该信号集中添加或删除某种有效信号。

4、sigprocmask函数

调用函数 sigprocmask 可以读取或更改进程的信号屏蔽字 ( 阻塞信号集 )
#include <signal.h>
int sigprocmask(int how, const sigset_t *set, sigset_t *oset); 
返回值:若成功则为0,若出错则为-1
如果调用 sigprocmask 解除了对当前若干个未决信号的阻塞 , 则在 sigprocmask 返回前 , 至少将其中一个信号递达。
通过man sigprocmask命令可以看到

how参数的取值:

我们通过代码来测试一下:

#include<signal.h>
#include<iostream>
#include <sys/types.h>
#include <unistd.h>


int main()
{
    sigset_t set,oset;
    sigemptyset(&set);
    sigemptyset(&oset);
    sigaddset(&set,SIGINT);//屏蔽2号信号
    sigprocmask(SIG_BLOCK,&set,&oset);
    while(true)
    {
        std::cout<<"我是"<<getpid()<<"号进程"<<std::endl;
        sleep(1);
    }
    return 0;
}

运行代码后我们使用Ctrl+c发出2号信号,没有停止

因为2号信号已经被屏蔽,就算使用kill命令发出也是一样的:

 

那么我们来解除阻塞后会不会恢复正常呢:

#include<signal.h>
#include<iostream>
#include <sys/types.h>
#include <unistd.h>


int main()
{
    sigset_t set,oset;
    sigemptyset(&set);
    sigemptyset(&oset);
    sigaddset(&set,SIGINT);//屏蔽2号信号
    sigprocmask(SIG_BLOCK,&set,&oset);
    while(true)
    {
        std::cout<<"我是"<<getpid()<<"号进程"<<std::endl;
        sleep(20);
        sigprocmask(SIG_UNBLOCK,&set,&oset);//20秒后解除阻塞
    }
    return 0;
}

可以看到

在未解除前,我们发送2号信号是没用的,但在20秒后,会自动处理2号信号退出。

因为阻塞并不是处理,信号依旧保持未决,暂时不递达,直到解除对信号的阻塞。

需要注意的是,9号信号是不会被屏蔽的,大家可以在上面代码的基础上测试。

5、sigpending 函数

sigpending 函数用于获取当前被阻塞但是仍然排队等待传递给进程的信号集合。也就是未决信号集

int sigpending(sigset_t *set);
调用成功则返回 0, 出错则返回 -1。
我们使用下列代码来测试:
#include<signal.h>
#include<iostream>
#include <sys/types.h>
#include <unistd.h>

void printsigset(sigset_t *set)
{
    for(int i=31;i>=0;i--)
    {
        if(sigismember(set,i))
        {
            std::cout<<"1";
        }
        else
        {
            std::cout<<"0";
        }
    }
    std::cout<<std::endl;
}
int main()
{
    sigset_t set,oset;
    sigemptyset(&set);
    sigemptyset(&oset);
    sigaddset(&set,SIGINT);//屏蔽2号信号
    sigprocmask(SIG_BLOCK,&set,&oset);
    while(true)
    {
        std::cout<<"我是"<<getpid()<<"号进程"<<std::endl;
        sigpending(&oset);
        printsigset(&oset);
        sleep(1);
    }
    return 0;
}

运行后可以看到:

当收到2号进程后,信号集对应的位置置为1,但是没有被执行,因为2号信号被阻塞了,按Ctrl-\仍然可以终止程序,因为SIGQUIT信号没有阻塞。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

7天精通Web APIs——-Bom操作(理论+实战)(第五天)

一、window对象 1.1 window对象和bom的关系 首先理解dom和bom之间的关系 显然bom的范围比较大 bom的全称为浏览器对象模型 window是bom的核心对象&#xff0c;window里面有很多属性和方法&#xff0c;用于实现浏览器与 JavaScript 代码之间的交互。作为 JavaScript 的全局对…

项目管理-项目绩效域2/2

项目管理&#xff1a;每天进步一点点~ 活到老&#xff0c;学到老 ヾ(◍∇◍)&#xff89;&#xff9e; 何时学习都不晚&#xff0c;加油 八大绩效域包括&#xff1a;“团干部 策划开公交” 团队、干系人、不确定性、测试、规划、开发方法与生命周期、项目工作、交付。 上节…

淘宝评论电商API接口:便捷查询商品真实评价

随着电商的快速发展&#xff0c;用户对于商品的评价越来越重要。淘宝作为中国最大的电商平台&#xff0c;拥有海量的商品和用户评价数据。联讯数据为了提供便捷的商品评价查询服务&#xff0c;淘宝推出了评论电商API接口。 什么是淘宝评论电商API接口 淘宝评论电商API接口是淘…

抖音赚钱可以看看这些小众赛道,很多人都赚到了自己的第一个一百万!2024适合小白入手的项目!白手起家新手小白创业真经

抖音创业最大的魅力是什么&#xff1f; 如果你还想创业&#xff0c;还想在抖音这个赛道上发光发热&#xff0c;不妨停下来思考一下这个问题。 那就是可以让一个及其小众的小品类的产品&#xff0c;捅破天花板&#xff01;达到一个不可思议的销售额&#xff01;这就是我的答案&…

Windows注册表

注册表 一.概述 注册表&#xff08;Registry&#xff09;是Microsoft Windows中的一个重要的数据库&#xff0c;用于[存储系统]和[应用程序]的设置信息。早在[Windows 3.0]推出[OLE]技术的时候&#xff0c;注册表就已经出现。随后推出的[Windows NT]是第一个从系统级别广泛使…

Python:一种强大的编程语言与无限可能

引言 Python是一种易于学习且功能强大的编程语言&#xff0c;它被广泛用于各种领域&#xff0c;包括数据科学、人工智能、Web开发、系统自动化等。Python以其简洁的语法、丰富的库和易于阅读的风格&#xff0c;成为了许多开发者的首选。本文将探讨Python的特性和应用&#xff…

CSS:一篇教会你用CSS装饰你的HTML文本

目录 ▐ CSS概述 ▐ CSS基本语法 ▐ 选择器 ▐ 修饰文本 ▐ 修饰背景 ▐ 伪类 ▐ 透明度 ▐ 标签的分类 ▐ display属性 ▐ div>标签 ▐ span>标签 ▐ CSS概述 • 全称Cascading Style Sheets 级联样式表 • css是一种样式表语言&#xff0c;用于为HTML文档控制外观&am…

DDPM与扩散模型

很早之前就新建了一个专栏从0开始弃坑扩散模型 ,但发了一篇文章就没有继续这一系列&#xff0c;在这个AIGC的时代&#xff0c;于是我准备重启这个专栏。 整个专栏的学习顺序可以见这篇汇总文章 这是本专栏的第一章 目录 引言生成模型的发展历程 引言 扩散模型( Diffusion Mode…

虹科Pico汽车示波器 | 免拆诊断案例 | 2010款凯迪拉克SRX车发动机无法起动

故障现象 一辆2010款凯迪拉克SRX车&#xff0c;搭载LF1发动机&#xff0c;累计行驶里程约为14.3万km。该车因正时链条断裂导致气门顶弯&#xff0c;大修发动机后试车&#xff0c;起动机运转有力&#xff0c;但发动机没有着机迹象&#xff1b;多起动几次&#xff0c;火花塞会变…

手动实现简易版RPC(四)

手动实现简易版RPC(四) 往期内容 手动实现简易版RPC&#xff08;一&#xff09;&#xff1a;RPC简介及系统架构 手动实现简易版RPC&#xff08;二&#xff09;&#xff1a;简单RPC框架实现 手动实现简易版RPC(三)&#xff1a;mock数据生成 前言 接上几篇博客我们实现了最…

QT--3

Qt 1>将文本编辑器完整实现 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);this->resize(800,600);edit1 new QTextEdit(this);edit1->resize(600…

计算机网络技术主要学什么内容,有哪些课程

计算机网络技术专业是一个涉及理论与实践紧密结合的学科&#xff0c;主要学习内容有计算机网络基础、网络设备技术、网络编程等内容&#xff0c;以下是上大学网&#xff08;www.sdaxue.com&#xff09;整理的计算机网络技术主要学什么内容&#xff0c;供大家参考&#xff01; 基…

linux命令之scp

今天遇到一个情况&#xff0c;内网环境不能联网没法下载最新的tcpdump。但是本身有个系统的tcpdump是最新版的&#xff0c;我不想rz下载再sz上传&#xff0c;想到可以用scp来直接传输文件&#xff0c;刚好来了解一下。 用法解释 scp&#xff08;secure copy&#xff09;命令可…

《视觉十四讲》例程运行记录(1)—— 课本源码下载和3rdparty文件夹是空的解决办法

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、第二版十四讲课本源码下载1. 安装git工具 二、Pangolin下载和安装1. 源码下载2. Pangolin的安装(1) 安装依赖项(2) 源码编译安装(2) 测试是否安装成功 二、…

SpringCloud 集成consul,消费者报I/O error on GET request for...

创建消费者微服务&#xff0c;去调用生产者微服务的请求过程中&#xff0c;出现以下错误&#xff1a; 报错原因 因为在使用SpringCloudAlibaba中的Nacos框架时&#xff0c;自动整合了SpringCloud中的Ribbon框架中的负载均衡&#xff0c;因为微服务提供者有两个&#xff0c;在消…

C++初识多态(1)

1.多态要解决的问题&#xff08;引入&#xff09; 任何一种机制的存在&#xff0c;必然是有其存在的意义的&#xff0c;例如我们前面学过的函数重载&#xff0c;运算符重载&#xff0c;以及引用等等&#xff0c;都是解决一些特殊问题的&#xff1b; 下面通过一些具体的例子&a…

类和对象、this指针、类里的默认生成函数

&#x1f436;博主主页&#xff1a;ᰔᩚ. 一怀明月ꦿ ❤️‍&#x1f525;专栏系列&#xff1a;线性代数&#xff0c;C初学者入门训练&#xff0c;题解C&#xff0c;C的使用文章&#xff0c;「初学」C&#xff0c;linux &#x1f525;座右铭&#xff1a;“不要等到什么都没有了…

【仪酷LabVIEW AI工具包案例】使用LabVIEW AI工具包+YOLOv5结合Dobot机械臂实现智能垃圾分类

‍‍&#x1f3e1;博客主页&#xff1a; virobotics(仪酷智能)&#xff1a;LabVIEW深度学习、人工智能博主 &#x1f384;所属专栏&#xff1a;『仪酷LabVIEW AI工具包案例』 &#x1f4d1;上期文章&#xff1a;『【YOLOv9】实战二&#xff1a;手把手教你使用TensorRT实现YOLOv…

升级PQC后,「谷歌浏览器」却频频报错......

上周Chrome 124发布后&#xff0c;默认启用了新的抗量子X25519Kyber768封装机制&#xff0c;不过&#xff0c;一些谷歌Chrome用户在使用后反应说&#xff0c;新版本的浏览器在连接网站、服务器和防火墙时出现了问题。 谷歌在8月份开始测试后量子安全TLS密钥封装机制&#xff0c…

嫦娥六号近月制动成功,建立月球基地又迈进一步!

嫦娥六号探测器在近月制动的关键时刻&#xff0c;北京航天飞行控制中心内弥漫着紧张而庄重的氛围。每一个航天科技工作者都屏息以待&#xff0c;他们的眼神中充满了期待与自豪。随着一系列精妙绝伦的指令如同琴弦上的音符般流畅地奏响&#xff0c;嫦娥六号探测器在万众瞩目的目…
最新文章