深入了解linux系统—— 进程信号的产生

前言

进程在收到信号之后,可以立即处理,也可以在合适的时间再处理(1-31号普通信号可以不被立即处理)

信号不是被立即处理,信号就要被保存下来,让进程在合适的时间再去处理。

相关概念

在了解进程是如何保存信号之前,先了解一下一些概念:

  • 信号递达:进程实际执行信号的处理动作
  • 信号未决:信号从产生到递达的状态
  • 阻塞:进程可以阻塞某一个信号;(被阻塞的信号不会被递达,直到解除对信号的阻塞,该信号才会被递达)
  • 忽略:是进程对于已递达的信号的一种处理方式。

信号保存

进程要将信号保存下来,在合适的时候处理;保存信号不仅要保存是否存在信号,也要保存进程是否阻塞信号以及进程对于信号的处理方式。

Linux内核中,对于信号存在三张表分别是:blockpendinghandler;它们分别存储了进程对于信号的阻塞信号,收到信号以及进程对于信号的处理方式。

每一个信号都有阻塞、未决两个标识位以及处理动作,这分别和blockpendinghandler表一一对应。

  1. block表,表示进程对于信号的阻塞情况;
  2. pending表,表示处于未决的信号情况;
  3. handler表,函数指针表,存储着进程对于信号的处理方式。

对于blockpending,可以简单理解为位图,对于1-31号信号,每一个信号对应一个bit位;

blockbit位为1表示进程阻塞该信号,pendingbit位为1表示该信号处于未决状态(进程收到该信号)。

对于handler表,其存储的是进程对于信号的处理方式。

在这里插入图片描述

了解了信号的保存方式blockpendinghandler表;

那发送信号的本质就是将进程的task_struct中的pending表对应的bit位置1(修改内核数据结构对象)

进程处理信号本质就是检查进程task_structblock表是否阻塞信号、pending表是否存在信号,然后进行调用handler表中进程对于信号的处理方法。

信号集sigset_t

信号保存的blockpending表,都是以位图的方式来保存信号阻塞和未决的状态;01

对于阻塞和未决标识都可以使用sigset_t(信号集)这一数据类型来存储。

信号集sigset_t,可以表示信号有效无效的状态。

在阻塞信号集中,有效无效表示信号是否被阻塞。

在未决信号集中,有效无效表示信号是否处于未决状态。

信号集操作函数

对于sigset_t信号集,我们不清楚里面有什么;不能直接对信号集进程操作,需要用到特定的函数接口。

在这里插入图片描述

相关信号集操作函数,例如初始化sigemptyset(设置为0)、sigfillset(设置为1)、sigaddset(新增信号)、sigdelset(删除信号)等等。

初始化信号集

int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);

对于初始化信号集,分为两种:一是所有bit位设置为0、二是所有bit位设置为1

sigemptyset,初始化信号集,所有bit位设置为0

sigfillset,初始化信号集,所有bit位设置为1

新增信号

int sigaddset(sigset_t* set, int signum);

在信号集中,新增一个信号signum

删除信号

int sigdelsets(sigset_t* set, int signum);

在信号集set这,删除信号signum

对于上述的sigemptysetsigfilletsigaddsetsigdelset,这些函数返回值:

如果函数调用成功,返回0

函数调用失败,返回-1

判断信号是否存在

int sigismember(sigset_t* set, int signum);

sigismember函数用来判断信号集sig中是否存在信号signum

如果存在就返回1;如果不存在就返回0;如果函数调用失败就返回-1

系统调用

上述信号集操作函数,是修改当前已有信号集sigset_t

而在Linux内核中,存在block表和pending表来记录进程对于信号的屏蔽和未决状态;那我们能否修改内核中的block表呢?能否获取内核中的blockpending表呢?

当然是可以的,我们可以通过系统调用sigprocmasksigpending来对内核中进程的阻塞信号集未决信号集进行相关操作。

sigprocmask

调用该函数,可以修改或者读取信号屏蔽字

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

对于sigprocmask函数,一共存在三个参数:

第一个参数表示要对内核中的block(阻塞信号集)进行什么操作;how的取值如下图:

在这里插入图片描述

第二个参数set指向当前信号集,我们需要自己创建信号集;

第三个参数oldset是一个输出型参数,当调用sigprocmask修改内核阻塞信号集时,会将内核阻塞信号集输出到oldset指向的信号集中。

测试:这里简单调用setprocmask为进程添加屏蔽2号信号

#include <stdio.h>
#include <signal.h>
#include <iostream>int main()
{sigset_t set;sigemptyset(&set);//初始化信号集sigaddset(&set, 2);//在信号集中添加2号信号sigset_t oldset;sigprocmask(SIG_BLOCK, &set, &oldset);while (true){}return 0;
}

在这里插入图片描述

sigpending

int sigpending(sigset_t *set);

调用sigpending函数可以获取进程的pending表(未决信号集)。

在内核中pending表是记录进程2未决信号的状态的,给进程发信号的本质就是修改内核中进程的pending表。

在获取了进程的未决信号集之后,我们可以使用信号集相关操作函数来判断该信号集中是否存在未决的信号。

这里简单验证:阻塞的信号是不会被递达的;

void print_pending()
{// 获取pendingsigset_t set;sigpending(&set);//输出位图for (int i = 31; i >= 1; i--){if (sigismember(&set, i))std::cout << '1';elsestd::cout << '0';}std::cout << std::endl;
}
void handler(int sig)
{std::cout << "receive sig : " << sig << std::endl;
}int main()
{//自定义捕捉2号信号signal(2, handler);//屏蔽2号信号sigset_t set, oldset;sigemptyset(&set);sigaddset(&set,2);sigprocmask(SIG_BLOCK, &set, &oldset);int cnt = 10;while(cnt--){//输出pending表print_pending();if(cnt == 0){//解除对2号信号的屏蔽sigemptyset(&set);sigprocmask(SIG_SETMASK, &oldset,nullptr);}sleep(1);}return 0;
}

在这里插入图片描述

总结

简单总结上述内容:

信号保存:block信号屏蔽表、pending信号未决表、handler信号处理方式(函数指针表)

信号集sigset_t,相关操作:初始化、新增、删除、判断是否存在等等

系统调用:sigprocmask:获取或设置内核blcok表、sigpending获取内核pending表。

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

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

相关文章

【Bluedroid】蓝牙协议栈enable流程深度解析

本文详细剖析 Bluedroid 蓝牙功能启用的核心流程&#xff0c;从enable()函数触发开始&#xff0c;深入解析蓝牙协议栈的异步启动机制、核心协议模块初始化、硬件控制器绑定及状态同步全流程。重点阐述接口就绪性检查、异步线程管理、配置文件回调机制等关键环节&#xff0c;揭示…

各种开发语言主要语法对比

各类主流编程语言的语法有着显著差异&#xff0c;这些差异源于语言设计哲学&#xff08;简洁性 vs 显式性&#xff09;、应用领域&#xff08;系统级、Web、数据科学&#xff09;、运行方式&#xff08;编译 vs 解释&#xff09;以及支持的范式&#xff08;面向对象、函数式、过…

小鹏汽车6月交付车辆34,611辆,同比增长224%

小鹏汽车-W(09868)发布公告&#xff0c;2025年6月&#xff0c;小鹏汽车共交付智能电动汽车34,611辆&#xff0c;同比增长224%&#xff0c;这标志着小鹏汽车已连续第八个月交付量超过了30,000辆。2025年第二季度&#xff0c;小鹏汽车共交付103,181 辆智能电动车&#xff0c;创下…

深入理解观察者模式:构建松耦合的交互系统

在软件开发中&#xff0c;我们经常遇到这样的场景&#xff1a;一个对象的状态变化需要通知其他多个对象&#xff0c;并且这些对象需要根据变化做出相应的反应。比如&#xff0c;用户界面中的数据变化需要实时反映到多个图表上&#xff0c;或者电商系统中的库存变化需要通知订单…

React强大且灵活hooks库——ahooks入门实践之常用场景hook

什么是 ahooks&#xff1f; ahooks 是一个 React Hooks 库&#xff0c;提供了大量实用的自定义 hooks&#xff0c;帮助开发者更高效地构建 React 应用。其中场景类 hooks 是 ahooks 的一个重要分类&#xff0c;专门针对特定业务场景提供解决方案。 安装 ahooks npm install …

Qt常用控件之QWidget(一)

Qt常用控件之QWidget&#xff08;一&#xff09;1.QWidget2.enabled属性2.geometry&#x1f31f;&#x1f31f;hello&#xff0c;各位读者大大们你们好呀&#x1f31f;&#x1f31f; &#x1f680;&#x1f680;系列专栏&#xff1a;【Qt的学习】 &#x1f4dd;&#x1f4dd;本…

AIOT开发选型:行空板 K10 与 M10 适用场景与选型深度解析

前言 随着人工智能和物联网技术的飞速发展&#xff0c;越来越多的开发者、学生和爱好者投身于创意项目的构建。 在众多的开发板中&#xff0c;行空板 K10 和 M10 以其独特的优势脱颖而出。 本文旨在为读者提供一份详尽的行空板 K10 和 M10 对比分析&#xff0c;从适用场景、…

redis汇总笔记

语雀完整版&#xff1a; https://www.yuque.com/g/mingrun/embiys/calwqx/collaborator/join?tokensLcLnqz5Rv8hOKEB&sourcedoc_collaborator# 《Redis笔记》 Redis 一般问题 Redis内存模型&#xff08;I/O多路模型&#xff09;多路复用IO如何解释 为什么Redis要使用单线…

STM32用PWM驱动步进电机

硬件介绍&#xff1a;连线&#xff1a;注意这里stp连的是pwm脉冲&#xff0c;dir连的是方向到时候代码pwm波形就是从这里来的&#xff0c;具体接线根据你的代码来注意要点&#xff1a;步进电机和舵机驱动是不一样的&#xff0c;它是根据步长来移动的&#xff0c;所以要开一个中…

力扣25.7.10每日一题——重新安排会议得到最多空余时间 II

Description 今天这道题和昨天类似&#xff0c;只是允许顺序变化。 Solution 把会议区间视作桌子&#xff0c;空余时间视作空位&#xff0c;我们要把一个桌子移到别的空位中。 初步想法是枚举桌子&#xff0c;找一个长度大于等于桌子长度的空位移过去。看上去&#xff0c;找…

IP报文分片与重组原理及实现分析

IP报文分片与重组原理及实现分析 引用&#xff1a; ppp/net/packet/IPFragment.hppp/net/packet/IPFragment.cpp 1. IP分片原理 当IP数据包大小超过MTU&#xff08;最大传输单元&#xff09;时&#xff0c;路由器/主机将其分割为多个片段传输&#xff0c;每个片段包含&…

[python]在drf中使用drf_spectacular

安装drf_spectacular 文档 pypi链接:https://pypi.org/project/drf-spectacular/ 文档链接:https://drf-spectacular.readthedocs.io/en/latest/readme.html 安装步骤 在环境中添加 pip install drf-spectacular在setting的INSTALLED_APPS中添加 INSTALLED_APPS [# ALL…

【Datawhale AI 夏令营】 用AI做带货视频评论分析(二)

5.预训练模型跑分 回顾赛题 回顾赛题任务 挑战与难点&#xff1a; 标注数据少 ——> 半监督学习 or 数据增强 聚类分析噪点影响严重 回顾Baseline 问题&#xff1a; TF-IDF无法捕捉以下语义。聚类分析粗糙&#xff0c;未评估聚类质量。 提升方案&#xff1a; 分类任务…

SPSSPRO:数据分析市场SaaS挑战者的战略分析

目录 第一部分&#xff1a;执行摘要 第二部分&#xff1a;平台解构&#xff1a;产品、架构与用户体验 2.1 SaaS范式转移&#xff1a;架构与起源 2.2 功能能力&#xff1a;分析师的工具箱 2.3 “智能分析”的价值主张 第三部分&#xff1a;市场渗透与受众细分 3.1 目标用户…

低版本hive(1.2.1)UDF实现清除历史分区数据

目标&#xff1a;通过UDF实现对表历史数据清除 入参&#xff1a;表名、保留天数N 一、pom文件 <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.…

C++中顶层const与底层const

在C中&#xff0c;const关键字用于定义常量&#xff0c;但它在指针和引用上下文中会产生两种不同的常量性&#xff1a;顶层const&#xff08;top-level const&#xff09;和底层const&#xff08;low-level const&#xff09;。理解它们的区别是避免编译错误和提高代码质量的关…

“SRP模型+”多技术融合在生态环境脆弱性评价模型构建、时空格局演变分析与RSEI指数生态质量评价

集成云端、桌面端等环境&#xff0c;结合遥感云计算、GIS空间分析&#xff0c;R语言统计分析的优势&#xff0c;以分析生态环境脆弱性的时空演变为主线。通过本课程的学习&#xff0c;您将掌握&#xff1a;第一&#xff0c;收集各类指标数据&#xff0c;构建的“生态压力度-生态…

算法学习笔记:17.蒙特卡洛算法 ——从原理到实战,涵盖 LeetCode 与考研 408 例题

在计算机科学和数学领域&#xff0c;蒙特卡洛算法&#xff08;Monte Carlo Algorithm&#xff09;以其独特的随机抽样思想&#xff0c;成为解决复杂问题的有力工具。从圆周率的计算到金融风险评估&#xff0c;从物理模拟到人工智能&#xff0c;蒙特卡洛算法都发挥着不可替代的作…

Tortoise 设置

如何关闭 Windows 下 TortoiseGit 任务栏里窗口标题的分支显示 一、引言 TortoiseGit 是一个专为团队协作设计的 Git 图形化客户端&#xff0c;旨在解决版本控制中常见的问题&#xff0c;如冲突、回滚、历史查看等。本文档是 TortoiseGit 的使用手册前言部分&#xff0c;旨在向…

[论文阅读] 人工智能 + 软件工程 | AI助力软件可解释性:从用户评论到自动生成需求与解释

AI助力软件可解释性&#xff1a;从用户评论到自动生成需求与解释 Automatic Generation of Explainability Requirements and Software Explanations From User ReviewsarXiv:2507.07344 Automatic Generation of Explainability Requirements and Software Explanations From …