Linux--进程信号(pending, block, Handler)集

news2024/11/28 16:27:04

信号在产生之后,到未被处理的这段时间内,是保存在进程的PCB结构体内的一张位图中的,位图的每个比特位的编号就代表着改信号是否产生,比特位为1表示该信号产生,0表示不存在。

本篇文章就来详细的解答信号在内核中具体的保存和处理方式。

注意,本文谈到的都是非实时信号。

一,三大集合表

1,block集合表代表着该信号是否被阻塞,如果该某个信号的block位图被修改为1,即表示该信号被阻塞,即使产生了该信号,进程也不会处理该信号。

2,pending集合代表的是该信号是否产生了,如果对应的比特位为1,代表着该信号已经产生,如果此时该信号未被阻塞,那么就会在合适的时候对该信号进行处理。(这个合适的时候就是当进程从内核态转化为用户态的时候)。  处理的方式就是对应handler表中的方式。

3,handler集合代表着该信号的处理方式,处理方式有三种

        一是SIG_DFL,即该信号的默认处理方式,比如2号信号就是结束进程,那么当2号信号被处理的时候,进程就会被结束。

        二是SIG_IGN,即忽略该信号。当该信号需要被处理的时候,什么也不做,就是对该信号进行忽略处理。

        三是用户自定义方法,当我们用signal或者sigaction函数对某个信号设置了自定义的捕捉方法,那么该信号处理的时候就会调用我们自定义的方法,而不是默认的信号处理方法。

二,信号集

Linux系统为我们提供了对block和pending信号集的操作方式。

1,概念:

每个信号只有一个bit的未决标志,非0即1,不记录该信号产生了多少次,阻塞标志也是这样表示的。 因此,未决和阻塞标志可以用相同的数据类型sigset_t来存储,sigset_t称为信号集,这个类型可以表示每个信号 的“有效”或“无效”状态。

阻塞信号集也叫做当 前进程的信号屏蔽字(Signal Mask)。

在阻塞信号集中“有效”和“无效”的含义是该信号是否被阻塞,而在未决信号集中“有 效”和“无效”的含义是该信号是否处于未决状态。

未决状态是指一个信号产生但是还未被处理的状态。

 2,信号集操作函数

sigset_t类型对于每种信号用一个bit表示“有效”或“无效”状态,至于这个类型内部如何存储这些bit则依赖于系统 实现,从使用者的角度是不必关心的,使用者只能调用以下函数来操作sigset_ t变量。

#include <signal.h>  头文件

int sigemptyset(sigset_t *set);  将该信号集的所有比特位设置为0

int sigfillset(sigset_t *set);  将该信号集的所有比特位设置为1

int sigaddset (sigset_t *set, int signo);  为该信号集添加某个信号signo

int sigdelset(sigset_t *set, int signo);   为该信号集删除某个信号signo

int sigismember(const sigset_t *set, int signo);  查看该signo信号是否存在于该信号集中                                                                                    存在返回1 ,反之返回0

 通过以上的介绍,我们就可以自己先设置好一个信号集,将某个信号添加到我们自定义的信号集中,然后再通过下面的  sigprocmask  函数将自定义的信号集设置到进程的内核block信号集中。

sigprocmask函数

调用函数sigprocmask可以读取或更改进程的信号屏蔽字(阻塞信号集)。

#include  <signal.h>

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

返回值:若成功则为0,若出错则为-1

如果oset是非空指针,则读取进程的当前信号屏蔽字通过oset参数传出。如果set是非空指针,则 更改进程的信号屏蔽字,参数how指示如何更改。如果oset和set都是非空指针,则先将原来的信号 屏蔽字备份到oset里,然后 根据set和how参数更改信号屏蔽字。如果不需要备份老的信号屏蔽字就将oset设置为nullptr。

 sigpending函数

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

下面我们就使用上面谈到的函数写一个小的实验。

实验内容:

1,自定义一个信号集,将2号信号设置阻塞,并将该信号添加到该进程的内核block表中并         读取该进程原来的block表,将该表存放在我们自定义的oldset信号集中。

2,对2号信号进行捕捉,并在10秒内发送2号信号,观察结果。

3,在执行10秒之后,再将原本的block信号集设置回内核中。再次发送2号信号,观察结果

代码:

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

using namespace std;

void handler(int signo)
{
    cout << "signal num : " << signo  << " pid : "<< getpid() <<endl;
}
int main()
{
    signal(2, handler);//对2号信号设置自定义捕捉方法
    
    sigset_t set, oldset;
    //对自定义信号集进行初始化
    sigemptyset(&set);
    sigemptyset(&oldset);

    sigaddset(&set, 2);//将2好信号添加到set中
    
    //将set设置到该进程的内核block表中,并将原本的block表的信息存放到oldset中。
    sigprocmask(SIG_SETMASK, &set, &oldset);

    int cnt = 10;
    while(1)
    {
        //循环等待我们发送2号信号
        sleep(1);
        cout << "main pid : " << getpid() << endl;

        if(--cnt == 0)
        {
            sigprocmask(SIG_SETMASK, &oldset, nullptr);
        }
    }

    return 0;
}

实验现象:

 我们可以看到当我们在10秒内发送2好信号的时候,对2号信号的自定义捕捉的行为并没有发生。

因为此时的block表中2号比特位的值为1,表示该信号是被阻塞的状态。即使pending中的位图为1,2号信号也不会被处理。

而在10秒过后,原本老的block信号集被设置回内核中,即恢复了对2号信号的阻塞,所以2号信号就执行了我们自定义的捕捉方法。

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

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

相关文章

数字革命下的产品:百数十年变迁的启示与思考。

随着数字化时代的到来&#xff0c;软件开发成为各行各业不可或缺的一部分。然而&#xff0c;传统的软件开发方法需要长时间的开发周期&#xff0c;高昂的成本和大量的人力资源。因此&#xff0c;低代码开发平台应运而生。低代码开发平台通过简化开发人员的工作和加速软件开发流…

故障分析 | 一条本该记录到慢日志的 SQL 是如何被漏掉的

背景 生产环境中 select count(*) from table 语句执行很慢&#xff0c;已经远超 long_query_time 参数定义的慢查询时间值&#xff0c;但是却没有记录到慢日志中。在测试环境也很容易复现出该问题&#xff0c;慢查询日志确实没有记录 select count(*) 语句。 慢查询相关参数…

数据结构入门-排序

排序的概念及其英语 排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的顺序排列起来的操作。稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录&a…

【网络】计算机中的网络

目录 &#x1f341;计算机网络 &#x1f341;计算机网络模型 &#x1f341;布线工程 &#x1f341;布线系统 &#x1f990;博客主页&#xff1a;大虾好吃吗的博客 &#x1f990;专栏地址&#xff1a;网络专栏 计算机网络 计算机网络的功能 数据通信、资源共享、增加可靠性、提…

Dubbo——SpringBoot集成Dubbo(@Autowired和@Reference的区别、Dubbo的服务治理)

Dubbo——原生API实现远程调用_Strine的博客-CSDN博客 在上一篇文章中我们讲了如何使用原生API发起远程调用&#xff0c;显然这种方式肯定是非常麻烦的&#xff0c;因此我们这里就讲如何使用SpringBoot去集成Dubbo将这些配置简化。 生产者服务 添加配置文件 dubbo:applicat…

如何安装Maven并在IDEA配置

下载 1.进入官网完成下载&#xff0c;下载好后解压到你喜欢的目录中去即可&#xff01; Maven – Download Apache Maven 2.解压出来就能看到以下目录结构&#xff0c;我们关注conf目录即可 3.配置Maven的本地仓库&#xff0c;进入conf目录并打开settings.xml&#xff0c;往下…

8.3 综合案例2.0-扫码支付二维码生成

综合案例2.0-扫码支付二维码生成 扫码支付完整流程案例说明1.硬件2.连线图 搭建云平台环境1.添加设备2.创建设备类型3.功能定义&#xff08;创建物模型&#xff09; 代码1.更改MQTT信息2.测试 扫码支付完整流程 参考链接微信支付开发者文档 &#xff08;1&#xff09;商户后台…

数据分析09——Pandas中的索引设置/排序/数据统计(异常值处理)

1、Pandas中的索引设置&#xff1a; Series重置索引 重置索引&#xff1a;s2 s1.reindex([1, 2, 3, 4, 5]) # 这种情况即使列表中索引给多了也没事&#xff0c;会自动填充空值。重置索引&#xff1a;s3 s1.reindex([1, 2, 3, 4, 5], fill_value0) # 这种情况列表中索引给多了…

从0开始 莫比乌斯函数和反演 学习笔记

莫比乌斯 0 前言 建议先看这篇比较简略的文章&#xff08;有大概了解&#xff09; 莫比乌斯函数_为最后的荣光的博客-CSDN博客 再根据个人情况食用本篇博客 1 莫比乌斯函数 1 1 定义 首先对 n n n 唯一分解&#xff1a; 唯一分解&#xff1a; 唯一分解定理一篇就够了_求…

Springboot——根据需求创建后端接口

需求分析: 具体返回如下JSON格式数据 含有四个属性列:id 和 username 和photo 和followerCount 第一步: 首先按照下面文章创建一个模板项目 SpingBoot——SB整合MB的web项目模板_北岭山脚鼠鼠的博客-CSDN博客 第二步: 使用如下的建表语句在一个数据库中新建一个用户表 CREA…

【C++进阶之路】类和对象(下)

文章目录 一.再谈构造函数初始化对象的两种方式1.函数体内赋值2.初始化列表深入理解初始化列表 3.explicit隐式类型转换 二.static成员引言static成员static成员函数练习 三.友元引入友元函数友元类 四.内部类基本概念练习 五 .匿名对象引入匿名对象补充&#xff1a;编译器的优…

一百一十三、DBeaver——从hive同步数据到clickhouse

目标&#xff1a;把hive的DM层结果数据导出到clickhouse数据库&#xff0c;试了kettle、sqoop等多种方法都报错&#xff0c;尤其是kettle&#xff0c;搞了大半天发现还是不行。结果目前就只能用DBeaver同步数据。 准备工作&#xff1a;hive和clickhouse中都建好表 第一步&…

$nextTick与原生js先渲染dom再执行函数的方式

$nextTick与原生js先渲染dom再执行函数的方式 vue的$nextTick 简述 Vue.js 的 $nextTick 方法是用于在 DOM 更新后执行延迟回调的方法。 当 Vue.js 更新 DOM 后&#xff0c;有时候需要执行一些操作&#xff08;如获取更新后的 DOM 元素的位置等&#xff09;&#xff0c;但是…

2023年美国大学生数学建模竞赛C题预测Wordle的结果解题全过程文档及程序

2023年美国大学生数学建模竞赛 C题 预测Wordle的结果 原题再现&#xff1a; 背景介绍   Wordle是纽约时报目前每天提供的一个流行谜题。玩家通过在六次或更短时间内猜出一个至五个字母的单词来解决这个谜题&#xff0c;每次猜测都会得到反馈。在这个版本中&#xff0c; 每个…

30Wqps+闲鱼优惠中台,如何架构的?

说在前面 在尼恩的&#xff08;50&#xff09;读者社群中&#xff0c;经常遇到一个 非常、非常高频的一个面试题&#xff0c;但是很不好回答&#xff0c;类似如下&#xff1a; 千万级数据&#xff0c;如何做系统架构&#xff1f;亿级数据&#xff0c;如何做做系统架构&#xf…

2022年美国大学生数学建模竞赛E题森林的碳封存解题全过程文档及程序

2022年美国大学生数学建模竞赛 E题 森林的碳封存 原题再现&#xff1a; 背景   正如我们所知&#xff0c;气候变化对生命构成了巨大威胁。为了减轻气候变化的影响&#xff0c;我们需要采取有效的行动来减少大气中温室气体的含量。仅仅减少温室气体排放是不够的。我们需要努…

Redis可持久化详解2

目录 ​编辑 Redis的持久化配置参数&#xff1a; 2.Redis的性能问题&#xff1a; 3保持久化数据的完整性和正确性&#xff1a; 4.Redis的集群技术&#xff1a; 总结&#xff1a; Redis持久化不得不注意的一些地方。 Redis的持久化配置参数&#xff1a; save&#xff1a;指…

MySQL之InnoDB表空间

前言 本文章收录在MySQL性能优化原理实战专栏&#xff0c;点击此处查看更多优质内容。 本文摘录自 ▪ 小孩子4919《MySQL是怎样运行的&#xff1a;从根儿上理解MySQL》 通过前边的内容&#xff0c;相信大家都知道了表空间是一个抽象的概念&#xff0c;对于系统表空间来说&am…

Unity 全新的输入系统

选new的那个 会重启ide 然后去package manager里把这个装上 创建配置文件 文档地址 https://docs.unity3d.com/Packages/com.unity.inputsystem1.5/manual/index.html 创建完了是这样的 设置成这样 记住 value 和 vector2 然后就可以 选择 上下左右了 之前不设置 value…

【macOS】:macbook 安装了两个macOS后,设置默认启动的顺序

【macOS】&#xff1a;macbook 安装了两个macOS后&#xff0c;设置默认启动的顺序 如果你的 MacBook 安装了两个 macOS 操作系统&#xff0c; 你可以通过以下步骤设置默认启动的顺序&#xff1a; 1. 点击苹果菜单&#xff0c;选择“系统偏好设置”。 2. 点击“启动磁盘”选…