当前位置: 首页 > news >正文

什么是软中断

部分内容来源:小林Coding


什么是中断

什么是中断?

在计算机中,中断是系统用来响应硬件设备请求的一种机制

操作系统收到硬件的中断请求,会打断正在执行的进程,然后调用内核中的中断处理程序来响应请求


中断-例子

这样的解释可能过于学术了,容易云里雾里,我就举个生活中取外卖的例子。


小林中午搬完砖,肚子饿了,点了份白切鸡外卖,这次我带闪了,没有被某团大数据杀熟。虽然平台上会显示配送进度,但是我也不能一直傻傻地盯着呀,时间很宝贵,当然得去干别的事情,等外卖到了配送员会通过「电话」通知我,电话响了,我就会停下手手中地事情,去拿外卖。

这里的打电话,其实就是对应计算机里的中断

没接到电话的时候,我可以做其他的事情,只有接到了电话,也就是发生中断,我才会停下当前的事情,去进行另一个事情,也就是拿外卖

从这个例子,我们可以知道,中断是一种异步的事件处理机制,可以提高系统的并发处理能力


中断请求存在的问题

操作系统收到了中断请求会打断其他进程的运行

所以中断请求的响应程序,也就是中断处理程序,要尽可能快的执行完,这样可以减少对正常进程运行调度地影响

而且,中断处理程序在响应中断时,可能还会「临时关闭中断」

这意味着,如果当前中断处理程序没有执行完之前,系统中其他的中断请求都无法被响应

也就是说中断有可能会丢失,所以中断处理程序要短且快

存在的问题:

  1. 中断请求会打断其他进程的运行
  2. 中断请求会导致【临时关闭中断】,可能会导致其他设备的中断请求丢失

中断请求的问题-例子

还是回到外卖的例子,小林到了晚上又点起了外卖,这次为了犒劳自己,共点了两份外卖,一份小龙虾和一份奶茶,并且是由不同地配送员来配送,那么问题来了,当第一份外卖送到时,配送员给我打了长长的电话,说了一些杂七杂八的事情,比如给个好评等等,但如果这时另一位配送员也想给我打电话。

很明显,这时第二位配送员因为我在通话中(相当于关闭了中断响应),自然就无法打通我的电话,他可能尝试了几次后就走掉了(相当于丢失了一次中断)


什么是软中断

中断的两个阶段

中断请求的处理程序应该要短且快,这样才能减少对正常进程运行调度地影响

而且中断处理程序可能会暂时关闭中断,这时如果中断处理程序执行时间过长,可能在还未执行完中断处理程序前,会丢失当前其他设备的中断请求

那 Linux 系统为了解决【中断处理程序执行过长】和【中断丢失】的问题,将中断过程分成了两个阶段

这两个阶段分别是「上半部分和下半部分」

  • 上半部分:用来快速处理中断,一般会暂时关闭中断请求,主要负责处理跟硬件紧密相关或者时间敏感的事情。
  • 下半部分:用来延迟处理上半部未完成的工作,一般以「内核线程」的方式运行。

例子-网卡接收网络包

网卡收到网络包后,通过 DMA 方式将接收到的数据写入内存

接着会通过硬件中断通知内核有新的数据到了

于是内核就会调用对应的中断处理程序来处理该事件

这个事件的处理也是会分成上半部和下半部

上部分:上部分要做的事情很少,会先禁止网卡中断,避免频繁硬中断,而降低内核的工作效率。接着,内核会触发一个【软中断】把一些处理比较耗时且复杂的事情交给「软中断处理程序」去做,也就是中断的下半部

下部分:其主要是需要从内存中找到网络数据,再按照网络协议栈,对网络数据进行逐层解析和处理,最后把数据送给应用程序

中断处理程序的上部分和下半部可以理解为:

  • 上半部直接处理硬件请求,也就是硬中断,主要是负责耗时短的工作,特点是快速执行
  • 下半部是由内核触发,也就说软中断,主要是负责上半部未完成的工作,通常都是耗时比较长的工作,特点是延迟执行


 

还有一个区别

硬中断(上半部)是会打断 CPU 正在执行的任务,然后立即执行中断处理程序

而软中断(下半部)是以内核线程的方式执行,并且每一个 CPU 都对应一个软中断内核线程,名字通常为「ksoftirqd/CPU 编号」,比如 0 号 CPU 对应的软中断内核线程的名字是 ksoftirqd/0

不过,软中断不只是包括硬件设备中断处理程序的下半部,一些内核自定义事件也属于软中断,比如内核调度等、RCU 锁(内核里常用的一种锁)等


系统中有哪些软中断

在 Linux 系统里,我们可以通过查看 /proc/softirqs 的内容来知晓「软中断」的运行情况

以及 /proc/interrupts 的内容来知晓「硬中断」的运行情况

你可以看到,每一个 CPU 都有自己对应的不同类型软中断的累计运行次数

有 3 点需要注意下

第一点:

要注意第一列的内容,它是代表着软中断的类型

在我的系统里,软中断包括了 10 个类型,分别对应不同的工作类型

NET_RX 表示网络接收中断

NET_TX 表示网络发送中断

TIMER 表示定时中断

RCU 表示 RCU 锁中断

SCHED 表示内核调度中断

第二点:

要注意同一种类型的软中断在不同 CPU 的分布情况,正常情况下,同一种中断在不同 CPU 上的累计次数相差不多,比如我的系统里,NET_RX 在 CPU0、CPU1、CPU2、CPU3 上的中断次数基本是同一个数量级,相差不多。

第三点:

这些数值是系统运行以来的累计中断次数,数值的大小没什么参考意义

但是系统的中断次数的变化速率才是我们要关注的,我们可以使用

watch -d cat /proc/softirqs 

查看中断次数的变化速率

前面提到过,软中断是以内核线程的方式执行的,我们可以用 ps 命令可以查看到

ps aux | grep softirq

下面这个就是在我的服务器上查到软中断内核线程的结果:

可以发现,内核线程的名字外面都有有中括号

这说明 ps 无法获取它们的命令行参数,所以一般来说,名字在中括号里的都可以认为是内核线程

而且,你可以看到有 4 个 ksoftirqd 内核线程,这是因为我这台服务器的 CPU 是 4 核心的

每个 CPU 核心都对应着一个内核线程


如何定位软中断导致的CPU使用率过高问题? 

可以用 top 命令来查看当前系统的软中断情况

上图中的黄色部分 si ,就是 CPU 在软中断上的使用率

而且可以发现,每个 CPU 使用率都不高,两个 CPU 的使用率虽然只有 3% 和 4% 左右,但是都是用在软中断上了。

另外,也可以看到 CPU 使用率最高的进程也是软中断 ksoftirqd

因此可以认为此时系统的开销主要来源于软中断。

如果要知道是哪种软中断类型导致的,我们可以使用

watch -d cat /proc/softirqs

查看每个软中断类型的中断次数的变化速率

一般对于网络 I/O 比较高的 Web 服务器,NET_RX 网络接收中断的变化速率相比其他中断类型快很多

如果发现 NET_RX 网络接收中断次数的变化速率过快,接下来就可以使用

sar -n DEV 

查看网卡的网络包接收速率情况,然后分析是哪个网卡有大量的网络包进来

接着,在通过 tcpdump 抓包分析这些包的来源

如果是非法的地址可以考虑加防火墙

如果是正常流量,则要考虑硬件升级等


软中断-快速复习

什么是中断:

响应硬件设备请求的一种机制

操作系统收到硬件的中断请求,会打断正在执行的进程,然后调用内核中的中断处理程序来响应请求

中断是一种异步的事件处理机制,可以提高系统的并发处理能力


中断存在的问题:

  1. 中断请求会打断其他进程的运行
  2. 中断请求会导致【临时关闭中断】,可能会导致其他设备的中断请求丢失

什么是【临时中断关闭】:

当前中断处理程序没有执行完之前,系统中其他的中断请求都无法被响应


中断的两个阶段:

Linux 为了解决【中断处理程序执行过长】和【中断丢失】,将中断过程分成了两个阶段

【上半部分】:用来快速处理中断,一般会暂时关闭中断请求,主要负责处理跟硬件紧密相关或者时间敏感的事情。

【下半部分】:用来延迟处理上半部未完成的工作,一般以「内核线程」的方式运行

中断处理程序的上部分和下半部可以理解为:

  • 上半部直接处理硬件请求,也就是硬中断,主要是负责耗时短的工作,特点是快速执行
  • 下半部是由内核触发,也就说软中断内核会触发一个【软中断】把一些处理比较耗时且复杂的事情交给「软中断处理程序」去做,主要是负责上半部未完成的工作,通常都是耗时比较长的工作,特点是延迟执行

人话:

【硬中断】:解决【中断处理程序执行过长】。CPU 会立即暂停当前任务,优先执行硬中断处理程序,硬中断的任务都是耗时短的

【软中断】:解决【中断丢失】。处理硬中断中 【来不及做的耗时任务】硬中断处理完毕后,CPU 恢复正常调度时,内核会检查是否有未处理的软中断,然后在合适的时机(如中断上下文结束后、内核线程调度时)执行


硬中断和软中断的区别:

硬中断(上半部)是会打断 CPU 正在执行的任务,然后立即执行中断处理程序

而软中断(下半部)是以内核线程的方式执行


系统中的软中断:

通过 /proc/softirqs 的内容来知晓「软中断」的运行情况

可以查看

  1. 软中断的类型
  2. 同一种类型的软中断在不同 CPU 的分布情况
  3. 中断次数的变化速率

如何定位软中断导致的CPU使用率过高问题:

  1. 查看每个软中断类型的中断次数的变化速率
watch -d cat /proc/softirqs
  1. 查看网卡的网络包接收速率情况,通过 tcpdump 抓包分析这些包的来源
sar -n DEV 
http://www.dtcms.com/a/266080.html

相关文章:

  • 使用Visual Studio 2022创建CUDA编程项目
  • Python爬虫 XPath 三方库lxml
  • Unity Android与iOS自动重启
  • Java综合练习04
  • js代码中的作用域
  • 深度学习×第4卷:Pytorch实战——她第一次用张量去拟合你的轨迹
  • Mausezahn - 网络流量生成与测试工具(支持从链路层到应用层的协议模拟)
  • C++ 解决类相互引用导致的编译错误
  • 状态码301和302的区别
  • 智能设备远程管理:基于OpenAI风格API的自动化实践
  • 渗透靶机 Doctor 复盘
  • 粘包问题介绍
  • JS模块导出导入笔记 —— 默认导出 具名导出
  • 【嵌入式电机控制#8】编码器测速实战
  • C++讲解—类(2)
  • MCP+Cursor入门
  • AI 日报:阿里、字节等企业密集发布新技术,覆盖语音、图像与药物研发等领域
  • 前缀和与差分算法详解
  • 线程池相关介绍
  • SpringSecurity01
  • 【libm】 7 双精度正弦函数 (k_sin.rs)
  • 从混沌到澄明,AI如何重构我们的决策地图与未来图景
  • 把大象塞进冰箱总共分几步:讲讲dockerfile里conda的移植
  • IOC容器讲解以及Spring依赖注入最佳实践全解析
  • XILINX FPGA如何做时序分析和时序优化?
  • Linux之Socket编程Tcp
  • 【BurpSuite 2025最新版插件开发】基础篇7:数据的持久化存储
  • snail-job的oracle sql(oracle 11g)
  • 百度捂紧“钱袋子”
  • 冒泡排序及其优化方式