Unix信号

news2024/11/17 22:43:29

文章目录

  • 信号概念及产生
    • 键盘事件eg
    • 软件中断eg
    • 硬件中断eg
  • 信号处理方式
    • PCB中关于信号的数据结构
    • 信号捕捉
  • 信号集sigset_t
    • sigprocmask
    • sigpending
  • 信号处理程序
    • signal、sigaction
    • 可重入函数
    • 可靠信号
  • kill、raise

信号概念及产生

信号是一种异步通知机制,内核通过信号告知目标进程某一事件已经发生,请求进程对该信号做出处理。例如我们在命令行上敲下ctrl+c其实就是发送了一个终止信号给前台进程组,前台进程在收到终止信号后会被强行终止。信号的产生方式有很多,如键盘事件,软件中断,硬件中断……

Unix标准提供了一组标准的信号集合,可以通过kill -l命令查看,每一个信号是一个宏常量,被扩展为一个整型类型。

image-20241116082927052

注:(没有0号信号和32、33号信号)

键盘事件eg

  1. CTRL+C,向前台进程组发送终止信号,强制结束前台进程组运行
  2. CTRL+Z,向前台进程组发送挂起信号,暂停前台进程组的运行

…………

(键盘事件的目标都是前台进程组)

软件中断eg

  1. 进程自身调用sleep函数
  2. 进程自身调用raise函数
  3. 进程自身调用abort函数

…………

硬件中断eg

  1. 除0错误
  2. 缺页中断
  3. 段错误

…………

信号处理方式

进程可以针对不同的信号设置不同的处理方式,分别对应默认处理(SIG_DEF)、忽略处理(SIG_IGN)、自定义处理;忽略处理及进程不对信号产生任何相应,默认处理对于大部分信号来说是终止进程,自定义处理即信号处理时调用用户自定义的回调函数。

SIGKILL(9) 和 SIGSTOP(19) 信号不可被自定义

PCB中关于信号的数据结构

在信号产生时进程并不会立刻对信号做出相应,处于这个时间窗口的信号称之为未决信号(挂起信号)

当进程对收到的信号做出处理称之为信号递达

进程可以选择阻塞某些信号的递达,即阻塞信号阻塞信号不等于忽略信号,忽略信号属于信号递达方式之一

PCB中维护了进程的三个关于信号的数据结构

  1. 未决信号集
  2. 阻塞信号集
  3. 信号处理集

其中未决信号集和阻塞信号集是内核定义的一种位图类型==(sigset_t信号集)==,而信号处理集是一个函数指针数组,绑定着各个信号的处理方式

从逻辑结构上看如下图所示

image-20241116084432231

当信号发生时由内核在进程PCB中设置相应的信号位,进程在合适的时机对该信号做出相应。

时间窗口
信号发生
内核将PCB中的未决信号集相应位置设1
目标信号在阻塞信号集中是否为1
信号处理完毕
从信号处理集中获取函数地址回调

信号捕捉

信号的捕捉是一个复杂流程,它发生于内核态回变到用户态的时刻,充斥着用户态和内核态的切换。具体过程如下

  1. 用户态下因为中断进入内核
  2. 内核中断处理完毕后递送信号
  3. 如果处理方式为忽略或默认则在内核态直接完成
  4. 如果处理方式为自定义则返回用户态完成
  5. 用户态处理完成后返回再次进入内核
  6. 在内核态中恢复上下文后返回用户态继续执行
忽略或默认
自定义
中断发生
切换至内核态
调用中断处理程序并递达信号
信号处理方式检查
内核态处理
返回用户态后处理
再次进入内核
恢复上下文
切换至用户态
结束

==为什么对于自定义处理需要返回在用户态完成:==这一步主要为了安全,在用户态下进程收到诸多限制,可以避免执行恶意逻辑破坏内核数据

信号集sigset_t

由于不同的信号数量可能会超过一个整型数的位数,Unix提供的系统基本数据类型sigset_t被广泛用于信号相关的API,如果我们需要查看或设置未决信号集或阻塞信号集,往往都要通过sigset_t参数进行操作。POSIX标准定义了有关于信号集数据类型的5的API

#include <signal.h>
int sigemptyset(sigset_t* set);  //将信号集所有位都置0
int sigfillset(sigset_t* set);   //将信号集所有位都置1
int sigaddset(sigset_t* set,int signo); 	 //信号集某一位(特定信号)置1
int sigdelset(sigset_t* set,int signo);      //信号集某一位置0
int sigismember(const sigset_t* set,int signo);  //判断某一位是否为1

POSIX规定在使用信号集数据类型必须先调用sigemptyset或sigfillset进行初始化操作

sigprocmask

sigprocmask可以查改进程的阻塞信号集(信号屏蔽字),它只适用于单线程进程

int sigprocmask(int how,const sigset_t* set,sigset_t* oset);
//oset用于返回当前信号屏蔽字
//set和how共同绝对对信号屏蔽字的处理

how的取值

  • SIG_BLOCK : set对原信号屏蔽字进行新增操作
  • SIG_UNBLOCK :set对原信号屏蔽字进行删除操作
  • SIG_SETMASK :set对原信号屏蔽字进行覆盖操作

sigpending

sigpending可以查进程的未决信号集

int sigpending(sigset_t* set);

sigpending返回的信号集,比特位为1的信号因被阻塞而不能被传递。因此处于挂起状态。

信号处理程序

signal、sigaction

Unix提供了2个接口用于设置信号处理程序,一个是具备可移植性的sigaction、一个是不具备可移植性的signal

sighandler_t signal(int signum, sighandler_t handler);
int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);

尽管在Linux下signal和sigaction的语义是一样,但是这不能保证signal在其他Unix平台的具有相同的语义,因此如果需要绑定自定义信号处理程序请使用sigaction

typedef void (*sighandler_t)(int); //sighandler_t是一个函数指针,规定了信号处理函数无返回且仅有一个int参数

struct sigaction {
void (*sa_handler)(int); //信号处理程序1
void (*sa_sigaction)(int, siginfo_t *, void *); //信号处理程序2,siginfo_t是一个结构体,保存了信号处理程序的各种信息

​ sigset_t sa_mask; //信号掩码
​ int sa_flags; //选项,默认传0,具体参看手册
​ };

信号处理程序1和2只能二选一

sa_mask的作用:参数信号集用于设置阻塞信号,可以保证信号处理程序执行过程中不被指定信号所中断,当信号处理程序结束后进程的信号屏蔽字将复原

可重入函数

可重入函数被定义为被中断后续还能正常执行的函数,这些函数都具有一个普遍的特征——不涉及对全局数据的修改。与之相反的是不可重入函数,不可重入函数如果在执行过程中因为信号中断,而信号处理程序也调用了一次同样的函数,就可能发生未定义行为。因此不可重入函数不应该被用于信号处理程序。(针对信号的可重入函数为异步信号安全函数,针对线程的可重入函数为线程安全函数)

信号处理函数应该只执行简单的操作,避免修改全局变量。

下图是Unix环境下已知的可重入函数image-20241116095305960

可靠信号

大部分Unix系统只会对信号做出1次递送,如果一个信号在已经在未决信号中,之后再次发生相同的信号,那么后发生的信号将被忽略,即第二次信号丢失了,这类信号称为不可靠信号。与之相对于的是可靠信号,对于可靠信号内核会为这些信号进行排队,保证不会有信号丢失。其中1~31是不可靠信号,34-64为可靠信号。

kill、raise

kill用于向一个进程或一组进程发送信号

raise用于向自身发送一个信号

int raise(int signo);
int kill(pid_t pid,int signo);

raise(signo) <==> kill(getpid(),signo);

kill中pid不同取值具有不同意义

image-20241116102016154

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

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

相关文章

如何解决由于找不到d3dx9_43.dll导致游戏启动失败?这里是如何解决的完整指南

遇到“由于找不到d3dx9_43.dll”错误时&#xff0c;很多用户可能会感到困惑和无助。这个问题通常发生在尝试启动游戏或使用基于DirectX的应用程序时。d3dx9_43.dll是Microsoft DirectX软件的一部分&#xff0c;专门用于处理复杂的图形计算&#xff0c;缺少它意味着某些图形功能…

任务函数分析

一、页面存储栈 PageStack 1、头文件 #include "ui.h"#define MAX_DEPTH 6typedef long long int StackData_t;typedef struct {StackData_t Data[MAX_DEPTH];uint8_t Top_Point;}user_Stack_T;uint8_t user_Stack_Push(user_Stack_T* stack, StackData_t datain)…

Springboot 微信小程序定位后将坐标转换为百度地图坐标,在百度地图做逆地址解析

问题解析以及解决思路 业务:微信小程序定位后,将坐标转换为百度地图坐标,在百度地图做逆地址解析 问题:微信小程序的定位是拿的腾讯地图的经纬度,但是我们app端这边使用的百度地图,如果直接使用腾讯地图的经纬度再使用腾讯地图的逆地址解析需要腾讯和百度商业授权,为了减少授权…

vue注册全局组件,其他地方可以直接方便的调用

文章目录 问题注册全局组件完结 问题 本来我们想使用某个组件&#xff0c;需要在各个地方引入对应的参数&#xff0c;并配置好components内容&#xff0c;才可以使用 但是随着用的越来越多&#xff0c;这种方法变得重复且易出错 注册全局组件 修改main.js文件&#xff0c;放…

Kubernetes 10 问,测测你对 k8s 的理解程度

Kubernetes 10 问 假设集群有 2 个 node 节点&#xff0c;其中一个有 pod&#xff0c;另一个则没有&#xff0c;那么新的 pod 会被调度到哪个节点上&#xff1f; 应用程序通过容器的形式运行&#xff0c;如果 OOM&#xff08;Out-of-Memory&#xff09;了&#xff0c;是容器重…

Java项目实战II基于微信小程序的课堂助手(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 在数字化教…

高光谱深度学习调研

综述 高光谱深度学习只有小综述&#xff0c;没有大综述。小综述里面场景分类、目标检测的综述比较多。 Wang C, Liu B, Liu L, et al. A review of deep learning used in the hyperspectral image analysis for agriculture[J]. Artificial Intelligence Review, 2021, 54(7)…

抖音热门素材去哪找?优质抖音视频素材网站推荐!

是不是和我一样&#xff0c;刷抖音刷到停不下来&#xff1f;越来越多的朋友希望在抖音上创作出爆款视频&#xff0c;但苦于没有好素材。今天就来推荐几个超级实用的抖音视频素材网站&#xff0c;让你的视频内容立刻变得高大上&#xff01;这篇满是干货&#xff0c;直接上重点&a…

人工智能之数学基础:数学在人工智能领域中的地位

人工智能&#xff08;AI&#xff09;是一种新兴的技术&#xff0c;它的目标是构建能够像人类一样思考、学习、推理和解决问题的智能机器。AI已经成为了许多行业的重要组成部分&#xff0c;包括医疗、金融、交通、教育等。而数学则是AI领域中不可或缺的基础学科。本文将阐述数学…

高翔【自动驾驶与机器人中的SLAM技术】学习笔记(十三)图优化SLAM的本质

一、直白解释slam与图优化的结合 我从b站上学习理解的这个概念。 视频的大概位置是1个小时以后&#xff0c;在第75min到80min之间。图优化SLAM是怎么一回事。 slam本身是有运动方程的&#xff0c;也就是运动状态递推方程&#xff0c;也就是预测过程。通过t1时刻&#xff0c…

STM32单片机设计防儿童人员误锁/滞留车内警报系统

目录 目录 前言 一、本设计主要实现哪些很“开门”功能&#xff1f; 二、电路设计原理图 1.电路图采用Altium Designer进行设计&#xff1a; 2.实物展示图片 三、程序源代码设计 四、获取资料内容 前言 近年来在车辆逐渐普及的情况下&#xff0c;由于家长的疏忽&#xff0c;将…

stm32——通用定时器时钟知识点

&#xff08;该图来自小破站 铁头山羊老师的stm32标准库教学&#xff09;

GPIO相关的寄存器(重要)

目录 一、GPIO相关寄存器概述 二、整体介绍 三、详细介绍 1、端口配置低寄存器&#xff08;GPIOx_CRL&#xff09;&#xff08;xA...E&#xff09; 2、端口配置高寄存器&#xff08;GPIOx_CRH&#xff09;&#xff08;xA...E&#xff09; 3、端口输入数据寄存器&#xff…

CSS基础也要进行模电实验

盒子阴影 圆角边框已经介绍过哩&#xff0c;现在先介绍一下盒子阴影的效果如何实现 CSS3中新增了盒子阴影&#xff0c;可以使用box-shadow属性为盒子添加阴影 这是固定的语法&#xff1a; text-shadow: h-shadow v-shadow blur color; 它有这些可选的值&#xff1a; 哦。 …

i春秋-登陆(sql盲注爆字段,.git缓存利用)

练习平台地址 竞赛中心 题目描述 先登陆再说 题目内容 就是一个登录框 测试登录 用户名&#xff1a;admin or 11# 密码&#xff1a;随便输 返回密码错误 用户名&#xff1a;随便输 密码&#xff1a;随便输 返回用户名不存在 这里就可以确定时一个bool盲注了 这里提供一个lik…

探索KubeVirt:如何利用InfiniBand提升虚拟机性能

在高性能计算&#xff08;HPC&#xff09;中&#xff0c;网络性能对于集群效率起着至关重要的作用。为了支持大规模并行计算&#xff0c;HPC集群通常依赖高带宽、低延迟的网络&#xff0c;而InfiniBand&#xff08;IB&#xff09;正是其中的首选技术。它能够提供超过100Gbps的带…

基于树莓派的边缘端 AI 目标检测、目标跟踪、姿态估计 视频分析推理 加速方案:Hailo with ultralytics YOLOv8 YOLOv11

文件大纲 加速原理硬件安装软件安装基本设置系统升级docker 方案Demo 测试目标检测姿态估计视频分析参考文献前序树莓派文章hailo加速原理 Hailo 发布的 Raspberry Pi AI kit 加速原理,有几篇文章介绍的不错 https://ubuntu.com/blog/hackers-guide-to-the-raspberry-pi-ai-ki…

小白进!QMK 键盘新手入门指南

经常玩键盘的伙伴应该都知道&#xff0c;现在的键盘市场可谓是百花齐放&#xff0c;已经不是之前的单一功能产品化时代。我们可以看到很多诸如&#xff1a;机械轴键盘、磁轴键盘、光轴键盘、电感轴键盘&#xff0c;以及可能会上市的光磁轴键盘&#xff0c;更有支持屏幕的、带旋…

《操作系统 - 清华大学》3 -3:连续内存分配:内存碎片与分区的动态分配

文章目录 0. 概述1. 内存碎片问题2. 动态分配3. 首次适配算法4. 最优适配算法5. 最差适配算法 0. 概述 内存分配是操作系统管理过程中很重要的环节&#xff0c;首先需要考虑的是一块连续区域分配的过程&#xff0c;这个过程中会有很多问题&#xff0c;首先比较关注的一个问题是…

vue内置指令和自定义指令

常见的指令&#xff1a; v-bind : 单向绑定解析表达式, 可简写为 :xxx v-model : 双向数据绑定 v-for : 遍历数组/对象/字符串 v-on : 绑定事件监听, 可简…