中断和信号详解

news2025/6/1 8:19:21

三种中断

中断分为三种:硬件中断、异常中断、软中断

硬件中断

设备向中断控制器发送中断请求,中断控制器生成对应中断号,然后通过中断引脚向cpu发送高电平,cpu收到请求后不会立即处理,cpu会处理完当前指令,然后检查IF标志(状态寄存器保存)和中断引脚,然后从中断控制器获取中断号,陷入内核,去中断向量表中执行中断函数

IF标志不是表示有没有中断,而是开不开中断,IF如果是0,那就是关中断,表示中断不进行处理。当cpu处理一个中断时硬件会自动关中断,防止中断处理过程被新中断打断,毕竟中断处理也是在执行指令

异常中断

cpu在执行指令的时候,比如运算器中有除零  或者  mmu查页表时发现数据还没加载  或者  mmu查地址空间发现越界,那么cpu就会自动触发中断,然后陷入内核,执行对应中断函数

软中断

当使用系统调用的时候,系统调用会有int 0x80 或 syscall 指令来触发中断,因为中断是指令触发的,因此系统调用触发的中断又称为软中断。将系统调用号保存在寄存器里,然后由int 0x80触发中断,陷入内核,查找中断向量表80号中断函数,然后在中断函数里面会根据寄存器里系统调用号去系统调用表里执行对应系统调用

现代操作系统将系统调用表地址直接保存到寄存器,使用syscall直接去系统调用表里面调用系统调用,直接省去中断向量表查中断函数的时间

中断函数处理前上下文保存

每个进程都拥有自己的内核栈,cpu触发中断陷入内核,会将用户态的寄存器状态保存在先前运行进程的内核栈里,然后在此内核栈里执行中断函数,执行完后从内核栈里恢复寄存器,回到用户态

信号的执行

当cpu执行完中断函数,会检查pcb里thread_info里的标志位,此时cpu还没有从内核栈恢复触发中断时的用户态寄存器,如果TIF_SIGPENDING被设置,那就去从头遍历pending表,找到第一个被设置pending并且block没有被设置的信号,清除其pending位,然后切换到用户态,执行对应信号处理函数,执行完后回到内核态重新从头遍历pending表,重复以上操作,直到没有需要处理的信号后,从内核栈中恢复触发中断时的用户态寄存器,然后切换回用户态

struct task_struct {
    struct thread_info *thread_info; 
    // ...
};

struct thread_info {
    struct task_struct *task;  // 指向对应的PCB(task_struct)
    unsigned long flags;       // 包含TIF_SIGPENDING等标志位
    // ... 架构相关字段(如寄存器状态)
};

信号产生

1.硬件中断设置信号

ctrl + \ :

键盘给中断控制器发送中断请求,中断控制器生成中断号,用中断引脚通知cpu,cpu执行完指令后判断IF标志和中断引脚,获取中断号,陷入内核,执行中断函数。中断函数会给前台进程设置信号pending,然后信号就设置好了

至于SIGQUIT信号的处理,在即将从内核态回到用户态时,处理这个信号,在信号处理函数中,会将进程状态改为Z,并将pcb里信号码改成SIGQUIT,core dump也会被设置,然后释放pcb所管理的资源如mm_struct、页表、物理内存块

2.使用kill命令

kill -11 pid

给pid进程设置11号信号

3.使用函数设置信号

int kill ( pid_t pid, int sig);
给进程设信号
int raise ( int sig);
给当前进程设置信号
void abort ( void );
给当前进程设置SIGABRT
SIGABRT信号的默认行为是退出进程加核心转储。假如将SIGABRT信号自定义函数处理,如果里面有exit那就做正常退出,如果没有exit那在信号处理结束后会执行默认行为,不只是这个信号,很多信号的自定义处理都是这样

4.核心转储

进程异常退出可以设置核心转储,核心转储文件会保存进程用户空间里的内存数据,用于后期调试,文件名通常是core或core.pid。 默认情况下,系统通过 ulimit -c 限制core文件大小为0(即不生成)。可以用ulimit命令来改变这个限制, 在Shell中修改 ulimit -c 后,该Shell启动的所有子进程 均会继承此设置。
​临时生效​​(当前Shell会话)
ulimit -c unlimited  # 不限制core文件大小
ulimit -c 1024       # 限制core文件为1024KB

信号保存

struct task_struct {
        struct sighand_struct * sighand ;
        sigset_t blocked
        struct sigpending pending ;
//...
};
struct sigpending {
        struct list_head list ;
        sigset_t signal;
};
1. sigset_t 类型​
  • ​底层实现​​:sigset_t 是一个​​位图(bitmask)​​,用于表示信号集(每个信号对应一个 bit)。
  • ​用途​​:
    • 用于 sigprocmask()(设置阻塞信号)
    • 用于 sigpending()(获取待处理信号)
    • 用于 sigaction()(设置信号处理方式)
2. pending表里是待处理的信号,block表里是阻塞的信号。
3. ​ SIG_IGN​:信号直接被丢弃,不会进入  pending 表
     block ​:信号被暂时阻塞,会进入  pending  表,解除阻塞后被处理。

信号集操作函数

# 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);

​信号处理相关系统调用详解:sigprocmasksigpendingsigaction

1. sigprocmask

​功能​

  • 用于​​阻塞或解除阻塞​​某些信号。
  • 被阻塞的信号不会进行处理,而是进入 pending 表,等待解除阻塞后再处理。

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

参数说明
how指定如何修改信号屏蔽字:
• SIG_BLOCK:将 set 中的信号加入阻塞列表
• SIG_UNBLOCK:从阻塞列表中移除 set 中的信号
• SIG_SETMASK:直接设置阻塞列表为 set
set要修改的信号集(sigset_t 类型)
oldset返回旧的信号屏蔽字(可传 NULL

2. sigpending 

​功能​

  • 获取当前​​待处理​​的信号(即 pending 表中的信号)。

int sigpending(sigset_t *set);

3. sigaction — 设置信号处理方式​

​功能​

  • 比 signal() 更强大的信号处理函数,可以:
    • 指定信号处理函数(handler
    • 设置信号处理的行为(如屏蔽其他信号)
    • 获取旧的信号处理方式

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

参数说明
signum要设置的信号(如 SIGINTSIGTERM
act新的信号处理方式(struct sigaction
oldact返回旧的信号处理方式(可传 NULL

struct sigaction结构

struct sigaction {
    void (*sa_handler)(int);          // 信号处理函数(类似 signal())
    void (*sa_sigaction)(int, siginfo_t *, void *);  // 更高级的信号处理
    sigset_t sa_mask;                 // 执行信号处理时额外阻塞的信号
    int sa_flags;                     // 控制信号行为(如 SA_RESTART)
};

sa_mask用来设置阻塞信号,一般都会阻塞本身,这个阻塞的持续时间是本次信号处理的整个过程,直到从内核栈恢复寄存器准备切换用户态才会解除阻塞,这个阻塞保证了每个信号在整个过程只会被处理一次,防止了死循环

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

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

相关文章

游戏引擎学习第312天:跨实体手动排序

运行游戏并评估当前状况 目前排序功能基本已经正常&#xff0c;能够实现特定的排序要求&#xff0c;针对单一区域、单个房间的场景&#xff0c;效果基本符合预期。 不过还有一些细节需要调试。现在有些对象的缩放比例不对&#xff0c;导致它们看起来有些怪异&#xff0c;需要…

智警杯备赛--数据库管理与优化及数据库对象创建与管理

sql操作 插入数据 如果要操作数据表中的数据&#xff0c;首先应该确保表中存在数据。没有插入数据之前的表只是一张空表&#xff0c;需要使用insert语句向表中插入数据。插入数据有4种不同的方式&#xff1a;为所有字段插入数据、为指定字段插入数据、同时插入多条数据以及插…

MySQL 在 CentOS 7 环境下的安装教程

&#x1f31f; 各位看官好&#xff0c;我是maomi_9526&#xff01; &#x1f30d; 种一棵树最好是十年前&#xff0c;其次是现在&#xff01; &#x1f680; 今天来学习Mysql的相关知识。 &#x1f44d; 如果觉得这篇文章有帮助&#xff0c;欢迎您一键三连&#xff0c;分享给更…

K8S集群主机网络端口不通问题排查

一、环境&#xff1a; k8s: v1.23.6 docker: 20.10.14 问题和故障现象&#xff1a;devops主机集群主机节点到端口8082不通&#xff08;网络策略已经申请&#xff0c;并且网络策略已经实施完毕&#xff09;&#xff0c;而且网络实施人员再次确认&#xff0c;网络策…

python打卡day39

知识点回顾 图像数据的格式&#xff1a;灰度和彩色数据模型的定义显存占用的4种地方 模型参数梯度参数优化器参数数据批量所占显存神经元输出中间状态 batchisize和训练的关系 课程代码&#xff1a; # 先继续之前的代码 import torch import torch.nn as nn import torch.opti…

3.8.5 利用RDD统计网站每月访问量

本项目旨在利用Spark RDD统计网站每月访问量。首先&#xff0c;创建名为“SparkRDDWebsiteTraffic”的Maven项目&#xff0c;并添加Spark和Scala的依赖。接着&#xff0c;编写Scala代码&#xff0c;通过SparkContext读取存储在HDFS上的原始数据文件&#xff0c;使用map和reduce…

尚硅谷redis7 49-51 redis管道之理论简介

前提redis事务和redis管道有点像&#xff0c;但本质上截然不同 49 redis管道之理论简介 面试题 如何优化频繁命令往返造成的性能瓶颈&#xff1f; redis每秒可以承受8万的写操作和接近10万次以上的读操作。每条命令都发送、处理、返回&#xff0c;能不能批处理一次性搞定呢…

openEuler安装MySql8(tar包模式)

操作系统版本&#xff1a; openEuler release 22.03 (LTS-SP4) MySql版本&#xff1a; 下载地址&#xff1a; https://dev.mysql.com/downloads/mysql/ 准备安装&#xff1a; 关闭防火墙&#xff1a; 停止防火墙 #systemctl stop firewalld.service 关闭防火墙 #systemc…

基于python,html,flask,echart,ids/ips,VMware,mysql,在线sdn防御ddos系统

详细视频:【基于python,html,flask,echart,ids/ips,VMware,mysql,在线sdn防御ddos系统-哔哩哔哩】 https://b23.tv/azUqQXe

Git:现代软件开发的基石——原理、实践与行业智慧·优雅草卓伊凡

Git&#xff1a;现代软件开发的基石——原理、实践与行业智慧优雅草卓伊凡 一、Git的本质与核心原理 1. 技术定义 Git是一个分布式版本控制系统&#xff08;DVCS&#xff09;&#xff0c;由Linus Torvalds在2005年为管理Linux内核开发而创建。其核心是通过快照&#xff08;Sna…

NLua性能对比:C#注册函数 vs 纯Lua实现

引言 在NLua开发中&#xff0c;我们常面临一个重要选择&#xff1a;将C#函数注册到Lua环境调用&#xff0c;还是直接在Lua中实现逻辑&#xff1f; 直觉告诉我们&#xff0c;C#作为编译型语言性能更高&#xff0c;但跨语言调用的开销是否会影响整体性能&#xff1f;本文通过基准…

【计算机网络】第2章:应用层—Web and HTTP

目录 一、Web 与 HTTP 二、总结 &#xff08;一&#xff09;Web 的定义与功能 &#xff08;二&#xff09;HTTP 协议的定义与功能 &#xff08;三&#xff09;HTTP 协议的核心机制 1. HTTP 请求与响应流程 2. HTTP 的连接类型 3. HTTP 的状态码 &#xff08;四&#xf…

数字孪生技术赋能西门子安贝格工厂:全球智能制造标杆的数字化重构实践

在工业4.0浪潮席卷全球制造业的当下&#xff0c;西门子安贝格电子制造工厂&#xff08;Electronic Works Amberg, EWA&#xff09;凭借数字孪生技术的深度应用&#xff0c;构建起全球制造业数字化转型的典范。这座位于德国巴伐利亚州的“未来工厂”&#xff0c;通过虚实融合的数…

【图像处理基石】立体匹配的经典算法有哪些?

1. 立体匹配的经典算法有哪些&#xff1f; 立体匹配是计算机视觉中从双目图像中获取深度信息的关键技术&#xff0c;其经典算法按技术路线可分为以下几类&#xff0c;每类包含若干代表性方法&#xff1a; 1.1 基于区域的匹配算法&#xff08;Local Methods&#xff09; 通过…

day12 leetcode-hot100-19(矩阵2)

54. 螺旋矩阵 - 力扣&#xff08;LeetCode&#xff09; 1.模拟路径 思路&#xff1a;模拟旋转的路径 &#xff08;1&#xff09;设计上下左右方向控制器以及边界。比如zy1向右&#xff0c;zy-1向左&#xff1b;sx1向上&#xff0c;sx-1向下。上边界0&#xff0c;下边界hang-1&a…

密钥管理系统在存储加密场景中的深度实践:以TDE透明加密守护文件服务器安全

引言&#xff1a;数据泄露阴影下的存储加密革命 在数字化转型的深水区&#xff0c;企业数据资产正面临前所未有的安全挑战。据IBM《2025年数据泄露成本报告》显示&#xff0c;全球单次数据泄露事件平均成本已达465万美元&#xff0c;其中存储介质丢失或被盗导致的损失占比高达…

webpack打包基本配置

需要的文件 具体代码 webpack.config.js const path require(path);const HTMLWebpackPlugin require(html-webpack-plugin);const {CleanWebpackPlugin} require(clean-webpack-plugin); module.exports {mode: production,entry: "./src/index.ts",output: {…

酷派Cool20/20S/30/40手机安装Play商店-谷歌三件套-GMS方法

酷派Cool系列主打低端市场&#xff0c;系统无任何GMS程序&#xff0c;也不支持直接开启或者安装谷歌服务等功能&#xff0c;对于国内部分经常使用谷歌服务商店的小伙伴非常不友好。涉及机型有酷派Cool20/Cool20S /30/40/50/60等旗下多个设备。好在这些机型运行的系统都是安卓11…

LabVIEW旋转机械智能监测诊断系统

采用 LabVIEW 开发旋转机械智能监测与故障诊断系统&#xff0c;通过集品牌硬件与先进信号处理技术&#xff0c;实现旋转机械振动信号的实时采集、分析及故障预警。系统突破传统监测手段的局限性&#xff0c;解决了复杂工业环境下信号干扰强、故障特征提取难等问题&#xff0c;为…

【芯片设计中的跨时钟域信号处理:攻克亚稳态的终极指南】

在当今芯片设计中&#xff0c;多时钟域已成为常态。从手机SoC到航天级FPGA&#xff0c;不同功能模块运行在各自的时钟频率下&#xff0c;时钟域间的信号交互如同“语言不通”的对话&#xff0c;稍有不慎就会引发亚稳态、数据丢失等问题。这些隐患轻则导致功能异常&#xff0c;重…