Linux操作系统5-进程信号3(信号的捕捉流程,信号集,sigaction)

上篇文章:Linux操作系统5-进程信号3(信号的保存, 用户态与内核态,内核空间)-CSDN博客

本篇Gitee仓库:​​​​​​​myLerningCode/l26 · 橘子真甜/Linux操作系统与网络编程学习 - 码云 - 开源中国 (gitee.com)

本篇重点:信号的捕捉流程与信号集

目录

一. 信号的捕捉流程

1.1 信号捕捉后,什么时候处理?

1.2 信号集sigset_t 及其操作函数

 1.3 信号保存的测试

二. 信号捕捉的方法 

2.1 signal

2.2 sigaction 

2.3 多次接收相同信号


一. 信号的捕捉流程

1.1 信号捕捉后,什么时候处理?

        信号捕捉后,当由内核态转为用户态的时候处理(进入内核需要系统调用,中断,进程切换等操作)。

        切换到用户态时候,就会查找进程的Block表,Pending表,方法表这三个表。

        首先查找Block表,表中为1的直接忽略,若为0,则要找对应的Pending表。若Pending表为0,直接忽略,为1的话说明这个信号未阻塞并且收到这个信号,就会直接执行对应方法表中的方法

        当进程执行方法表中的方法时候,我们需要进入到内核态才能执行这部分代码。如果行为是用户自定义的,内核态也不能直接执行这部分代码,需要进入用户态之后再去执行相应的代码。执行完方法之后,会经过特定的调用重新回到内核态。

1.2 信号集sigset_t 及其操作函数

        Pending表就是 Pending信号集        Block表就是Block信号集

相关操作函数如下:

#include <signal.h>//将信号集set置空
int sigemptyset(sigset_t *set)int sigfillset(sigset_t *set);    //将set置1int sigaddset(sigset_t *set, int signo);    //添加signo到set中int sigdelset(sigset_t *set, int signo);    //删除set中的signoint sigismember(const sigset_t *set, int signo);    //判断一个signo是否在set中

sigpromask:用于修改Block表 

#include <signal.h>int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);//hao参数//SIG_BLOCK 将set添加到信号集oldset中 相当于 mask = mask | set//SIG_UNBLOCK 将oldset中的信号包含set的信号解除 相当于 mask = mask & (~set)//SIG_SETMASK    将当前信号集更改为mask 即 mask = set//oldset 输出型参数,更改信号屏蔽字之后,将之前的信号屏蔽字保存在oldset中。//set 使用上面的fill全置1或者其他调用之后,传入该调用即可进行屏蔽                                                                                                            

sigpending:用于修改Pending表 

#include <signal.h>int sigpending(sigset_t *set);
//set是输出型参数,根据输入set,将pending表保存在set中并且返回
//哪个进程使用sigpending就返回哪个表的pending表

通过 signal 我们可以修改方法表

通过 sigpromask 我们可以修改Block表

通过 sigpending 我们可以修改pending表

 1.3 信号保存的测试

        这里屏蔽2号信号,然后打印Block表

#include <iostream>
#include <string>
using namespace std;#include <unistd.h>
#include <signal.h>
#define BLOCK_SIGNAL 2
#define MAX_SIGNAL 31static void show(const sigset_t &pending)
{for (int signo = MAX_SIGNAL; signo >= 1; signo--){if (sigismember(&pending, signo))cout << "1";elsecout << "0";}cout << endl;
}int main()
{// 1.先尝试屏蔽指定的信号sigset_t block, oldblock, pending;// 1.1初始化sigemptyset(&block);sigemptyset(&oldblock);sigemptyset(&pending);// 1.2添加要屏蔽的信号sigaddset(&block, BLOCK_SIGNAL); //(到这里没有屏蔽信号,只是预定信息)// 1.3 屏蔽(设置进入内核)sigprocmask(SIG_SETMASK, &block, &oldblock);// 2.遍历打印Pending信号集while (true){// 2.1初始化sigemptyset(&pending);// 2.2获取pending表sigpending(&pending);// 2.3show(pending);sleep(1);}return 0;
}

测试结果如下:

 可以看到,当我们输入2号信号之后,Block表中的第2位由0变1

二. 信号捕捉的方法 

2.1 signal

        我们通过signal可以自定义我们的信号捕捉方法。

具体内容可以看这一篇文章:Linux操作系统5-进程信号2(信号的4种产生方式,signal系统调用)-CSDN博客

2.2 sigaction 

#include <signal.h>//函数原型
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)//act是输入型参数,old是输出型参数
//通过这个调用我们可以将act的方法输入。并将原本的方法保存到oldact中//sigaction是一个结构体,内部有方法表,block表

sigaction结构体的定义如下:

 

其中  sa_handler就是方法表        sa_mask就是Block表

我们可以通过sigaction来屏蔽某些信号同时设置某些信号的捕捉方法。

举例代码:

        这里屏蔽3号信号,同时自定义2号信号的捕捉方法

#include <iostream>
#include <string>
using namespace std;#include <unistd.h>
#include <signal.h>// 自定义信号处理
void handler(int signo)
{while (true){cout << getpid() << " 进程接收到信号:" << signo << " 并处理" << endl;sleep(1);}
}int main()
{struct sigaction act, oldact;act.sa_flags = 0;          // 默认设置为0即可act.sa_handler = handler;  // 设置默认方法sigemptyset(&act.sa_mask); // 将屏蔽信号清空// 可以通过mask来屏蔽相应的信号, 这里屏3信号sigaddset(&act.sa_mask, SIGQUIT);sigprocmask(SIG_SETMASK, &act.sa_mask, &oldact.sa_mask);// 捕捉信号,设置2号信号sigaction(SIGINT, &act, &oldact);int count = 0;while (true){cout << "我正在运行 pid:" << getpid() << " 次数:" << ++count << endl;sleep(1);}return 0;
}

运行结果如下:

可以看到,成功自定义了2号信号的捕捉方法。同时屏蔽了3号信号 

2.3 多次接收相同信号

如果一个信号在递达期间再次收到这个信号会咋样?

测试代码:

#include <iostream>
#include <string>
using namespace std;#include <unistd.h>
#include <signal.h>// 自定义信号处理
void handler(int signo)
{int cnt = 10;while (cnt > 0){cout << getpid() << " 进程接收到信号:" << signo << " [" << --cnt << "]" << endl;sleep(1);}
}int main()
{struct sigaction act, oldact;act.sa_flags = 0;          // 默认设置为0即可act.sa_handler = handler;  // 设置默认方法sigemptyset(&act.sa_mask); // 将屏蔽信号清空// 可以通过mask来屏蔽相应的信号, 这里屏3信号// sigaddset(&act.sa_mask, SIGQUIT);// sigprocmask(SIG_SETMASK, &act.sa_mask, &oldact.sa_mask);// 捕捉信号,设置2号信号sigaction(SIGINT, &act, &oldact);int count = 0;while (true){cout << "我正在运行 pid:" << getpid() << " 次数:" << ++count << endl;sleep(1);}return 0;
}

运行结果如下: 

         如果进程在递达某信号的时候,再次收到信号。由于当前正在处理这个信号,不会管这个信号直到信号递达结束。

1 我们在递达某一个信号期间,相同类型的信号无法被抵达 -- 因为递达某一个信号的时候,会将这个信号加入到屏蔽字(Block表)

2 当信号递达完毕,会解除某一个信号的屏蔽

3 如果信号递达完毕,这个信号仍在Pending表中,会再次递达这个信号

4 如果信号在递达期间,收到本身的信号,会将Pending表由0 -> 1 。如果多次收到这个信号,由1 -> 1 相当于什么也没做

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

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

相关文章

【机器学习chp10】降维——(核化)PCA + MDS + lsomap + 拉普拉斯特征映射 + t-NSE + UMAP

目录 一、降维的意义与本质 1、意义 2、本质 3、常见降维方法 &#xff08;1&#xff09;线性降维 &#xff08;2&#xff09;非线性降维 二、基于重构的降维 1、PCA 2、核化PCA &#xff08;1&#xff09;实现过程 步骤一&#xff1a;数据映射与核函数定义 步骤二…

代码的解读——自用

代码来自&#xff1a;https://github.com/ChuHan89/WSSS-Tissue?tabreadme-ov-file 借助了一些人工智能 run_pipeline.sh 功能总结 该脚本用于执行一个 弱监督语义分割&#xff08;WSSS&#xff09; 的完整流程&#xff0c;包含三个阶段&#xff1a; Stage1&#xff1a;训…

Powershell和BTEQ工具实现带多组参数和标签的Teradata数据库批量数据导出程序

设计一个基于多个带标签SQL模板作为配置文件和多组参数的Powershell代码程序和BTEQ工具&#xff0c;实现根据不同的输入参数&#xff0c;自动批量地将Teradata数据库的数据导出为CSV文件到指定目录上&#xff0c;标签和多个参数&#xff08;以“_”分割&#xff09;为组成导出数…

CF 118A.String Task(Java实现)

题目分析 输入一个字符串&#xff0c;遍历每一个字符&#xff0c;如果是元音字母就删除&#xff0c;辅音字母就在其前面增加一个.&#xff0c;且所有字母输出都是小写。 思路分析 将输入的字符串改为字符数组&#xff0c;考虑到任意位置插入的情况&#xff0c;所以主要选择Lin…

LLM进阶

prologue&#xff1a;最近大模型火出天际&#xff0c;I’m definitely aware I’m late to the party&#xff0c;2022年毕业之后就很少在系统的跟踪一个domain了&#xff0c;所以这次下定决心要跟踪一下大模型的技术细节和实现过程&#xff0c;不做AI丁真 本文三条主线&#…

Ubuntu 下查看进程 PID 和终止进程方法

查看进程 PID 使用 ps 命令: ps aux | grep <process_name>例如&#xff0c;查看名为 python 的进程&#xff1a; ps aux | grep python使用 pgrep 命令: pgrep <process_name>例如&#xff0c;查看名为 python 的进程&#xff1a; pgrep python使用 top 命令: top…

Java基础语法练习34(抽象类-abstract)(抽象类最佳实践-模版设计模式)

一抽象类-abstract、 父类方法不确定性的问题故将该方法设计为抽象类&#xff08;没有实现的方法&#xff09;&#xff0c;但一般来说被子类继承然后实现 细节&#xff1a; 1、抽象类不可以被实例化 2、抽象类可以不包含抽象方法而且可以有实现的其他非抽象方法 3、abstra…

Android SDK与NDK的区别

Android SDK&#xff08;Software Development Kit&#xff09;与NDK&#xff08;Native Development Kit&#xff09;在Android应用开发中各自扮演着重要角色&#xff0c;它们之间存在显著的区别。以下是Android SDK与NDK的主要区别&#xff1a; 一、定义与用途 Android SDK…

DeepSeek在PiscTrace上完成个性化处理需求案例——光流法将烟雾动态可视化

引言&#xff1a;PiscTrace作为开放式的视图分析平台提供了固定格式的类型参数支持个性化定制处理需求&#xff0c;本文一步步的实现光流分析按照不同需求根据DeepSeek的代码处理视频生成数据。 光流法&#xff08;Optical Flow&#xff09;是一种基于图像序列的计算机视觉技术…

Linux网络 TCP全连接队列与tcpdump抓包

TCP全连接队列 在 Linux 网络中&#xff0c;TCP 全连接队列&#xff08;也称为 Accept 队列&#xff09;是一个重要的概念&#xff0c;用于管理已经完成三次握手&#xff0c;即已经处于 established 状态但尚未被应用程序通过 accept( ) 函数处理的 TCP 连接&#xff0c;避免因…

flex布局自定义一行几栏,靠左对齐===grid布局

模板 <div class"content"><div class"item">1222</div><div class"item">1222</div><div class"item">1222</div><div class"item">1222</div><div class"…

使用3090显卡部署Wan2.1生成视频

layout: post title: 使用3090显卡部署Wan2.1生成视频 catalog: true tag: [Kubernetes, GPU, AI] 使用3090显卡部署Wan2.1生成视频 1. 环境说明2. 模型下载3. 克隆仓库4. 安装依赖5. 生成视频 5.1. 使用generate脚本生成5.2. 使用gradio启动UI界面生成 5.2.1. 启动gradio服务5…

Prompt生成-Prompt工程师

# Role:Prompt工程师 ## Attention&#xff1a; - 我总是被老板骂写不出来Prompt&#xff0c;如果你能写出优秀的Prompt会避免让我失业&#xff0c;请认真思考并竭尽全力&#xff0c;拜托了&#xff01; ## Profile: - Author:pp - Version:2.1 - Language:中文 - Description:…

数据存储:一文掌握RabbitMQ的详细使用

文章目录 一、RabbitMQ简介二、RabbitMQ的概述2.1 基本概念2.2 实际应用场景三、RabbitMQ的安装与配置3.1 安装RabbitMQ3.2 启用管理插件四、使用Python操作RabbitMQ4.1 安装Pika库4.2 生产者示例4.3 消费者示例4.4 发布/订阅模式示例五、RabbitMQ的高级特性5.1 消息持久化5.2 …

Mixture of Experts与Meta Learning深度学习中的两大变革性技术

1. 引言 随着人工智能&#xff08;AI&#xff09;和深度学习技术的迅猛发展&#xff0c;创新的架构和算法不断涌现&#xff0c;推动了智能系统性能的显著提升。在这些技术中&#xff0c;Mixture of Experts (MoE) 和 Meta Learning Algorithms (MLA) 是两种极具影响力的方法。…

【新立电子】探索AI眼镜背后的黑科技,FPC如何赋能实时翻译与语音识别,点击了解未来沟通的新方式!

在全球化的今天&#xff0c;语言障碍成为人们沟通与交流的一大难题。AI眼镜作为一种新兴的智能设备&#xff0c;正在通过实时翻译与语音识别功能&#xff0c;打破语言壁垒&#xff0c;为人们提供无缝沟通的解决方案。FPC在AI眼镜中的应用&#xff0c;为实时翻译与语音识别功能的…

(十 三)趣学设计模式 之 模版方法模式!

目录 一、 啥是模板方法模式&#xff1f;二、 为什么要用模板方法模式&#xff1f;三、 模板方法模式的实现方式四、 模板方法模式的优缺点五、 模板方法模式的应用场景六、 总结 &#x1f31f;我的其他文章也讲解的比较有趣&#x1f601;&#xff0c;如果喜欢博主的讲解方式&a…

模型和数据集的平台之在Hugging Face上进行模型下载、上传以及创建专属Space

模型下载 步骤&#xff1a; 注册Hugging Face平台 https://huggingface.co/ 新建一个hf_download_josn.py 文件 touch hf_download_josn.py 编写hf_download_josn.py文件 import os from huggingface_hub import hf_hub_download# 指定模型标识符 repo_id "inter…

【弹性计算】弹性裸金属服务器和神龙虚拟化(二):适用场景

弹性裸金属服务器和神龙虚拟化&#xff08;二&#xff09;&#xff1a;适用场景 1.混合云和第三方虚拟化软件部署2.高隔离容器部署3.高质量计算服务4.高速低时延 RDMA 网络支持场景5.RISC CPU 支持6.GPU 性能无损输出 公共云服务提供商推出 弹性裸金属服务器&#xff0c;很显然…

python容器之常用操作

以列表list为例&#xff0c;这个list相当于c中的数组或vector容器。那列表有哪些常用的操作呢&#xff1f; 获取列表的长度 list [1,2,3,4,5] //获取列表的长度 length len(list) 注意这里与c不同&#xff0c;c中的容器都是有各自的定义&#xff0c;每种容器类型都实现了自…