深入理解网络中断:原理与应用

在这里插入图片描述

🔭 嗨,您好 👋 我是 vnjohn,在互联网企业担任 Java 开发,CSDN 优质创作者
📖 推荐专栏:Spring、MySQL、Nacos、Java,后续其他专栏会持续优化更新迭代
🌲文章所在专栏:网络 I/O
🤔 我当前正在学习微服务领域、云原生领域、消息中间件等架构、原理知识
💬 向我询问任何您想要的东西,ID:vnjohn
🔥觉得博主文章写的还 OK,能够帮助到您的,感谢三连支持博客🙏
😄 代词: vnjohn
⚡ 有趣的事实:音乐、跑步、电影、游戏

目录

  • 前言
  • 中断的种类
    • 中断
    • 异常
  • 中断号
  • INT 指令
  • 接收中断号方式
  • CPU 收到中断号如何处理
  • 软中断
    • 硬中断、软中断区别
    • 软中断细枝末节
    • 小结
  • 总结

前言

在了解 Epoll 多路复用模型时,操作系统底层的中断处理机制是要有一定认识的

任何操作系统内核的核心任务,都包含有对连接到计算机上的硬件设备进行有效管理,如:硬盘、鼠标、键盘以及无线电等,而当要管理这些设备,首先要和它们互相通信才行。

众所周知,处理器的速度跟硬件设备处理的速度不在一个数量级别上,因此,若内核采取让处理器向硬件发出一个请求,然后有一个专门等待回应的方法,显然查强人意,既然硬件的响应这么慢,那么内核就应该在此期间可以去处理其他的事务,等到硬件真正完成了请求的操作以后,再回过头来对它进行处理.

如何让处理器和硬件设备能够协同工作,且不会降低机器的整体性能?

轮询(polling) 可能是一种解决办法,它可以让内核定期对设备的状态进行查询,然后再作出相应的处理,不过这种方法很可能会让内核做很多无用的功,因为无论硬件设备是正在忙碌完成任务还是已经完成,轮询总会周期性的重复执行,更好的办法是提供一种机制,让硬件在需要的时候再向内核发出信号(由内核主动变为硬件主动)

由内核主动变为硬件主动:这就是中断机制

中断的种类

中断可分为中断和异常,异常又可以分为故障、陷阱和中止

CPU 提供了两种中断程序执行的机制:中断和异常

An interrupt is an asynchronous event that is typically by an I/O device
中断:中断就是一个异步事件,通常由 I/O 设备触发

An exception is a synchronous event that is generated when the processor detects one or more predefined while executing an instruction.
异常:异常是一个同步事件,是 CPU 在执行指令时检测到的反常条件,比如 > 除法异常、错误指令异常、缺页异常等

两者的执行机制,都是让 CPU 收到一个中断号,再到中断描述符表找出具体的执行处理的程序入口即可响应该中断事件要处理的事情.

中断

中断使得硬件得以发出通知给到处理器,例如:当你敲击键盘时,键盘控制器(控制键盘的硬件设备)会发送一个中断,通知操作系统有键按下,中断本质上是一种特殊的电信号,由硬件设备发向处理器,处理器接收到中断以后,会马上向操作系统反映此信号的由来,然后就交由给操作系统负责处理这些新到来的数据

硬件设备生成中断时并不考虑与处理器的时钟同步,换句话就是说中断可以随时产生,因此,内核随时可能因为新到来的中断而被打断

整个操作系统就是一个由中断驱动的死循环,用最简单的伪代码解释再合适不过了,如下:

while(true) {
	doNothing();
}

所有的事情都是由操作系统提前注册的中断机制和其对应的中断处理函数来完成的,当有信号到来时,会通知操作系统来帮我们处理这些信号对应的事件,当没有任何操作系统处理的事件时,就停留在死循环里不做任何事情。

不同的硬件设备对应的中断不同,而每个中断都通过一个唯一的数字标志,因此,来自键盘的中断就有别于来自硬盘的中断,从而使得操作系统能够对中断进行区分,并知道是由那个硬件设备产生的哪个中断,这样,操作系统才能给不同的中断提供对应的中断处理程序。

异常

在操作系统中,异常与中断不同,它在产生时必须考虑与处理器时钟同步;实际上,异常也常常称为同步中断,在处理器执行到由于编程失误而导致的错误指令(如被 0 除)时,或者是在执行期间出现特殊情况(如缺页)必须靠内核来处理时,处理器就会产生一个异常

中断号

在提及中断时,说到了中断号,在发生中断或异常以后,都会给 CPU 发送一个中断号过去,那么 CPU 是如何接收到这个中断号的呢?

在这里插入图片描述

CPU 内部内置 APIC 单元,Intel多处理规范的核心就是高级可编程中断控制器(Advanced Programmable Interrupt Controllers–APICs)的使用。 CPU 通过彼此发送中断来完成它们之间的通信。

APIC 可编程中断控制器,它有很多的 IRQ 引脚线,接入了一堆能发出中断请求的硬件设备。当这些硬件设备给 IRQ 引脚线发出一个信号时,由于可编程中断控制器提前被设置好了 IRQ 与中断号之间的对应关系,所以就转化成了对应的中断号,把这个中断号存储在自己的一个端口上,然后给 CPU 的 INTR 引脚发送一个信号,CPU 收到 INTR 引脚信号以后,去刚刚的那个端口上可读取到这个中断号的值.

IRQ 是中断请求(Interrupt Request)的缩写,它在计算机中用来发送一个由其他硬件中断 CPU 的请求。
当一个设备请求中断时,INTR 值是来自各个设备的请求的逻辑或。处理IRQ 所涉及的事件序列:设备引发 IRQ,处理器中断当前正在执行的程序

最终的目标就是让 CPU 知道,有中断需要处理,并且也知道这个中断号是多少

在这里插入图片描述

如上图,这些中断值通常被称为中断请求(IRQ)线,每个 IRQ 线都会被关联一个数值,例如:在 PC 机上, IRQ 0 是时钟中断,IRQ 1 是键盘中断

比如:按下了键盘,最终到 CPU 那一边的反应就是得到了一个中断号 0x21

异常机制就非常简单,当 CPU 自身执行指令时检测到的一些反常情况,然后自己给自己一个中断号,无须外界提供

无论是中断还是异常,最终都是通过这种方式得到一个中断号,只不过中断是通过外部设备给 CPU 的 INTR 发送信号,异常是自身执行指令时发现特殊情况触发的,自己给自己一个中断号

INT 指令

另外一种方式可以给 CPU 一个中断号,这个就是大名鼎鼎的 INT 指令

INT 指令后面跟一个数字,相当于直接用指令的形式,告诉 CPU 一个中断号

比如:INT 0x80,就是告知 CPU 中断号是 0x80,它是由 Linux 内核提供的系统调用,就是用了 INT 0x80 这个指令

在这里插入图片描述

接收中断号方式

给 CPU 一个中断号有三种方式

  1. 通过中断控制器给 CPU 的 INTR 引脚发送信号,并且允许 CPU 从中断控制器的一个端口上读取中断号,比如:按下键盘上的某一个按键,最终会给 CPU 一个 0x21 中断号
  2. CPU 执行某条指令时发生了异常,给自身触发给自己一个中断号,比如:执行到了无效指令,CPU 会给自己一个 0x06 中断号
  3. 执行 INT n 指令,会直接给 CPU 一个中断号 n,比如:触发了 LInux 系统调用,实际上就是执行了 INT 0x80 指令,CPU 收到的中断号就是 0x80

CPU 收到中断号如何处理

CPU 收到一个中断号 n 以后,会去中断描述符表中寻找第 n 个中断描述符,从中断描述符中找到中断处理程序的地址,然后跳过去执行

更准确的来说,从中断描述符中找到的,并不直接是程序的地址,而是段选择子和段内偏移地址,然后,段选择子又会去全局描述符表(GDT Global Descriptor Table) 中寻找段描述符,从中取出段基地址,再由段基址+段内偏移地址,才能得到最终处理程序的入口地址

在这里插入图片描述

若在内存中开启了分页 > Page Cache,还要经历分页机制的转换

在操作系统中所有的地址转换,都需要经过分段机制和分页机制,这不是中断流程所持有的,可以直接理解为中断描述符表中存储的地址,直接当作 CPU 可以跳过去执行的程序入口地址即可。

在这里插入图片描述

中断描述符表是什么?

中断描述符表(IDT)本质上就是一个存放在内存中的数组,全称为 Interrupt Descriptor Table

中断描述符是什么?

中断描述符是中断描述符表这个数组里存储的数据结构,它内部存放了段选择子和段内偏移地址

CPU 如何找到中断描述符表?

CPU 提前预留了一个寄存器,叫做 IDTR 寄存器,这里面存放的就是中断描述符表的起始地址以及中断描述符表的大小

如上所说,若忽略分段和分页的处理过程,直接拿到的就是程序入口地址,CPU 在找到了程序的入口地址以后,它如何做的?

CPU 实际上做的事情就是压栈,并跳转到入口地址处执行代码,而压栈的目的就是为了保护现场(原来的程序地址、原来的程序堆栈、原来的标志位)和传递信息(错误码)

以上所说的中断内容都是硬中断,它是由 Intel CPU 硬件实现的中断机制,触发可以通过外部硬件,也可以通过软件的 INT 指令进行触发

与硬中断对应的还有软中断,软中断是纯粹由软件实现的一种类似中断的机制,实际上它就是模仿硬件,在内存的一个地方存储软中断的标志位,然后由内核中的一个线程不断轮询这些标志位,若哪个标志位是有效的,就寻找这个软中断对应的中断处理程序

软中断

前面所描述的硬中断并不是硬件中断,硬中断的概念范围更大.

硬中断包括中断、异常及 INT 指令的这种软件中断,整个中断机制是纯硬件实现的逻辑,不管是由谁触发的,都叫硬中断

这里也需要有软件的配合,软件需要提前把中断向量表提前写在内存里,并通过 IDTR 寄存器告诉 CPU 它的起始位置在哪

硬中断、软中断区别

软中断是纯软件实现的,从宏观和微观层面来说明它们之间的相同点和不同点

中断从宏观层面来看,就是打断当前正在运行的程序,转而去执行中断处理程序,执行完以后再返回到原始程序

从这个层面来看,硬中断可以达到这个效果,软中断也可以达到这个效果,两者效果是一样的

微观层面,两者的处理方式却大有不同

硬中断的微观层面,就是 CPU 会在每一个指令周期的最后,都会留一个 CPU 周期去查看是否有中断,若有中断,就把中断号取出来,去中断向量表中寻找中断处理程序,然后跳过去执行

软中断的微观层面,简单来说会有一个单独的守护进程,不断轮询一组标志位,若哪个标志位有值了,就去这个标志位对应的软中断向量表数组中的相应位置,找到软中断的处理函数(回调函数)然后跳过去执行

软中断细枝末节

软中断就是一组一位一位 bit 的软中断标志位,对应着软中断向量表中一个一个的中断处理函数,然后有一个内核守护进程不断去循环判断调用

软中断是 Linux 中处理一个中断的下半部分的主要方式,比如:Linux 某网卡接收到了一个数据包,此时会触发一个硬中断,由于处理数据包的过程比较耗时,而硬中断资源又非常的宝贵,若占着硬中断函数不返回,会影响其他硬中断的响应速度,假如说同时点击鼠标、按下键盘,所以一般 Linux 会把中断拆分为上下两部分执行,上半部分处理简单的逻辑,将下半部分直接丢给一个软中断去异步处理

小结

为了方便下篇 Epoll 多路复用模型的理解,中断这一块的工作机制需要有一定的理解

在这里插入图片描述

当客户端数据到达网卡以后,每个客户端 socketfd 都有各自的 buffer 缓冲区,网卡数据到达以后会有不同的中断标识会交由 DMA 去协调,DMA 此时会经过 kernel,再到 CPU 处基于系统调用所需要处理的函数,进行内核内的处理过程

DMA(Direct Memory Access) 协处理器,它是由内存里开辟的一块区域,可以加速应用程序与内核之间的访问,用来专门处理中断时,不阻塞现有硬件资源的使用,基于信号/异步的方式来告知硬件需要做事情了,你有新的工作需要处理

网卡到来的数据有不同的组装方式交由给 DMA 去协调处理,如下:

  1. 单个数据包触发中断
  2. Buffer:积攒一堆数据给 DMA 触发中断,常用的方式
  3. 轮询:频率太快,会给出一段时间轮询调用数据

应用程序与内核之间的中断,通过 INT 0x80 Hex 等十六进制标志位,将中断标志位给到 CPU 以后,它会根据中断向量表所匹配到的条目,基于中断处理函数去进行函数的处理工作.

中断最终会基于回调的方式,在处理 I/O 时,触发 event 回调事件

在 select/poll 模型之前的回调处理中,只是将网卡发来的数据,走内核网络层协议栈,经过传输控制层、网络层、链路层,最终关联到客户端 socketfd 的 buffer 缓冲区内,所以说,当你某个时间内从应用程序询问 kernel 哪些 fd 可读或可写,会有状态进行返回

若在内核中 event 回调函数处理的时候,再加入一些新的处理逻辑,所能实现的功能就大有不同了,关于下篇的 Epoll 多路复用也就是基于这些新的处理逻辑,来区分它与 select/poll 之间的优势的!!!

总结

该篇博文作为引入 Epoll 多路复用函数前的钩子,先简略得了解中断机制是怎样的「内核主动变为硬件主动」在其中说到了中断的种类:中断、异常,两者的本质都是让 CPU 收到一个中断号,再到中断描述符表找出具体的执行处理的程序入口即可响应事件要处理的事情,再者就是,给 CPU 一个中断号有三种方式:1、通过中断控制器给 CPU INTR 引脚发送信号,也就是硬件中断的方式,2、CPU 执行某条指令时发生了异常,自身会触发一个中断号,3、执行 INT n 指令,会直接给 CPU 一个中断号 n,这就是在软件中断场景下才会发生的,例如某些特定的系统函数调用;注意的是:整个中断机制都是由硬件实现的逻辑,不管是由谁触发的,都叫做硬中断;硬中断会留有一个 CPU 去查看是否有中断,有则处理;软中断会有一个单独的守护进程,不断去轮询标志位组中是否有标志位有值了,有值的情况下就会去中断向量表中找出具体的位置,然后找到软中断对应的回调函数进行执行;关于本篇讲解中断的细枝末节希望您能够喜欢,感谢三连支持!

参考文献:

  1. 《Linux 内核设计与实现》—(美)Robert Love 著
  2. 《Linux 源码趣读》— 闪客 著

学习帮助文档:

  • man pages:yum install man
  • pthread man pages:yum -y install man-pages

🌟🌟🌟愿你我都能够在寒冬中相互取暖,互相成长,只有不断积累、沉淀自己,后面有机会自然能破冰而行!

博文放在 网络 I/O 专栏里,欢迎订阅,会持续更新!

如果觉得博文不错,关注我 vnjohn,后续会有更多实战、源码、架构干货分享!

推荐专栏:Spring、MySQL,订阅一波不再迷路

大家的「关注❤️ + 点赞👍 + 收藏⭐」就是我创作的最大动力!谢谢大家的支持,我们下文见!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大数据技术8:StarRocks极速全场景MPP数据库

前言:StarRocks原名DorisDB,是新一代极速全场景MPP数据库。StarRocks 是 Apache Doris 的 Fork 版本。StarRocks 连接的多种源。一是通过这个 CDC 或者说通过这个 ETL 的方式去灌到这个 StarRocks 里面;二是还可以去直接的和这些老的 kafka 或…

C++ 模拟实现vector

目录 一、定义 二、模拟实现 1、无参初始化 2、size&capacity 3、reserve 4、push_back 5、迭代器 6、empty 7、pop_back 8、operator[ ] 9、resize 10、insert 迭代器失效问题 11、erase 12、带参初始化 13、迭代器初始化 14、析构函数 完整版代码 一、…

MyBatis 四大核心组件之 Executor 源码解析

🚀 作者主页: 有来技术 🔥 开源项目: youlai-mall 🍃 vue3-element-admin 🍃 youlai-boot 🌺 仓库主页: Gitee 💫 Github 💫 GitCode 💖 欢迎点赞…

【IDEA】IntelliJ IDEA中进行Git版本控制

本篇文章主要记录一下自己在IntelliJ IDEA上使用git的操作,一个新项目如何使用git进行版本控制。文章使用的IDEA版本 IntelliJ IDEA Community Edition 2023.3,远程仓库为https://gitee.com/ 1.配置Git(File>Settings) 2.去Git…

Leetcode刷题详解——仅仅反转字母

1. 题目链接:917. 仅仅反转字母 2. 题目描述: 给你一个字符串 s ,根据下述规则反转字符串: 所有非英文字母保留在原有位置。所有英文字母(小写或大写)位置反转。 返回反转后的 s 。 示例 1: 输…

docker-ubuntu中基于keepalived+niginx模拟主从热备完整过程

一、环境准备 🔗在Ubuntu中安装docker 二、主机 1、环境搭建 1.1 镜像拉取 docker pull ubuntu:16.041.2 创建网桥 docker network create -dbridge --subnet192.168.126.0/24 br11.3 启动容器 docker run -it --name ubuntu-1 --privileged -v /home/vac/l…

PPP协议概述与实验示例

PPP协议概述与实验示例 概述 PPP(Point-to-Point Protocol)是一种用于在点对点连接上传输多协议数据包的标准方法。它已经成为最广泛使用的互联网接入数据链路层协议,可以与各种技术结合,如ADSL、LAN等,实现宽带接入…

【rabbitMQ】rabbitMQ控制台模拟收发消息

目录 1.新建队列 2.交换机绑定队列 3.查看消息是否到达队列 总结: 1.新建队列 2.交换机绑定队列 点击amq.fonout 3.查看消息是否到达队列 总结: 生产者(publisher)发送消息,先到达交换机,再到队列&…

phpstudy小皮(PHP集成环境)下载及使用

下载 https://www.xp.cn/download.html直接官网下载即可,下载完解压是个.exe程序,直接点击安装就可以,它会自动在D盘目录为D:\phpstudy_pro 使用 phpMyAdmin是集成的数据库可视化,这里需要下载一下,在软件管理-》网站程…

linux逻辑卷LVM

创建LVMVG管理LV扩容 6.2.6 逻辑卷LVM LVM是Logical Volume Manager 的简称,译为逻辑卷管理,它是Linux下对硬盘分区的一种管理机制。LVM适合于管理大存储设备,并允许用户动态调整文件系统的大小。此外,LVM的快照功能可以帮助我们快…

第九天:信息打点-CDN绕过篇amp;漏洞回链amp;接口探针amp;全网扫描amp;反向邮件

信息打点-CDN绕过篇 cdn绕过文章:https://www.cnblogs.com/qiudabai/p/9763739.html 一、CDN-知识点 1、常见访问过程 1、没有CDN情况下传统访问:用户访问域名-解析服务器IP–>访问目标主机 2.普通CDN:用户访问域名–>CDN节点–>…

设计模式-外观模式

设计模式专栏 模式介绍模式特点应用场景外观模式和里氏替换原则的区别代码示例Java实现外观模式python实现外观模式 外观模式在spring中的应用 模式介绍 外观模式(Facade Pattern)是一种结构性设计模式,它隐藏了系统的复杂性,并向…

[后端卷前端2]

绑定class 为什么需要样式绑定呢? 因为有些样式我们希望能够动态展示 看下面的例子: <template><div><p :class"{active:modifyFlag}">class样式绑定</p></div> </template><script>export default {name: "goo…

Docker中的常见命令

Docker开机自启 systemctl enable dockerDocker容器开机自启 docker update --restartalways [容器名/容器id]案例&#xff1a;docker操作nginx 拉取Nginx镜像 docker pull nginx查看镜像 docker images创建并运行Nginx容器 docker run -d --name nginx -p 80:80 nginx查…

(NeRF学习)3D Gaussian Splatting Instant-NGP环境配置

学习参考&#xff1a; 3D gaussian splatting 安装步骤拆解23.9月3D Gaussian Splatting入门指南【五分钟学会渲染自己的NeRF模型&#xff0c;有手就行&#xff01;】 三维重建instant-ngp环境部署与colmap、ffmpeg的脚本参数使用 一、3D Gaussian Splatting &#xff08;一&…

airserver mac 7.27官方破解版2024最新安装激活图文教程

airserver mac 7.27官方破解版是一款好用的airplay投屏工具&#xff0c;可以轻松将ios荧幕镜像&#xff08;airplay&#xff09;至mac上&#xff0c;在mac平台上实现视频、音频、幻灯片等文件资源的接收及投放演示操作&#xff0c;解决iphone或ipad的屏幕录像问题&#xff0c;满…

【实战教程】PHP如何轻松对接阿里云直播?

1. 配置阿里云直播的推流地址和播放地址 使用阿里云直播功能前&#xff0c;首先需要在阿里云控制台中创建直播应用&#xff0c;然后获取推流地址和播放地址。 推流地址一般格式为&#xff1a; rtmp://{Domain}/{AppName}/{StreamName}?auth_key{AuthKey}-{Timestamp}-{Rand…

[虚拟机]使用VM打开虚拟机电脑重启解决方案。

问题&#xff1a;打开虚拟机点击启动后&#xff0c;电脑会自动重启。&#xff08;WINDOWS10 20版本&#xff09; 解决步骤&#xff1a; 1、对Windows功能进行操作。 上图三个启用。 上图一个取消。 再次打开后&#xff0c;不报警&#xff0c;显示下图问题&#xff1a; 继续解…

基于SpringBoot+Vue前后端分离的商城管理系统(Java毕业设计)

大家好&#xff0c;我是DeBug&#xff0c;很高兴你能来阅读&#xff01;作为一名热爱编程的程序员&#xff0c;我希望通过这些教学笔记与大家分享我的编程经验和知识。在这里&#xff0c;我将会结合实际项目经验&#xff0c;分享编程技巧、最佳实践以及解决问题的方法。无论你是…

【Linux】find . -perm 644 -exec ls -l {} \;

find . -perm 644 -exec ls -l {} ; find 命令使用 -perm 644 条件来查找文件权限为644的文件&#xff0c;然后通过 -exec ls -l {} \; 将这些文件传递给 ls -l 命令来显示详细的文件列表。 find . -perm 644&#xff1a;在当前目录及其子目录中查找文件权限为644的文件。 -e…