【C语言】linux内核软中断

一、什么是软中断?

内核中的软中断(Softirqs)和任务下半部(Tasklets)是Linux内核中用于在中断上下文之外处理中断服务的一种底层机制。这些机制解决了不能在中断服务例程(ISR)中执行耗时操作或者需要睡眠的操作的问题。软中断提供了一种在中断上下文中延迟处理的方法,允许中断处理分为两个阶段:顶半部和底半部。

顶半部(Top Half)

- 发生硬件中断时,首先会执行顶半部。
- 顶半部的代码通常运行在硬中断上下文,需要尽可能快地执行,因为在顶半部执行期间,相同的中断或其他中断可能被锁定,这会影响系统响应时间。
- 它通常负责快速执行与硬件交互的必要步骤,如读取寄存器或复位硬件中断状态,并且快速结束,以免长时间占用中断。

底半部(Bottom Half)

- 底半部是中断处理的延迟执行部分,用于执行更复杂或耗时的操作。
- 它在中断上下文之外执行,可以被其他中断打断。
- 底半部机制允许系统维持较高的响应性,因为顶半部可以快速释放中断线,让其他中断能够得到处理。

软中断(Softirqs)

- 软中断是Linux内核处理底半部工作的最原始的机制。
- 它们是静态定义的,数量固定,具体在<linux/interrupt.h>中定义。
- 每个CPU都有自己的软中断向量和状态。
- 软中断的处理是延迟的,常常是在中断返回后或者在其他处理器空闲时由内核调度器触发执行。
- 它们具有高性能,但开发起来相对复杂,因此Linux中还引入了更简化的底半部处理机制,即任务下半部(Tasklets)。

任务下半部(Tasklets)

- Tasklets是建立在软中断之上的一个简化的抽象,提供了更简单的接口。
- Tasklets可以动态创建,运行在软中断的上下文中,允许将小任务推迟到不会影响系统实时行为的时候执行。
- Tasklets可以被禁用和重新启用,但在设计上,同一个Tasklet在系统中的多个CPU之间不会并行执行。

软中断和任务下半部的处理通常发生在如下几个时间点:

1. 中断处理的硬中断返回后。
2. 当系统中断返回到用户空间前。
3. 内核检测到某个CPU运行在空闲循环(idle loop)时。
在多处理器系统中,软中断和任务下半部的处理需要考虑并发性和负载均衡,内核通常会在不同的CPU上分配这些任务,以充分利用系统资源。

二、软中断的实现

内核软中断(Softirqs)在Linux内核中是通过一系列底层机制实现的。下面是一个高层次的概述,展示了软中断是如何工作和实现的:
1. 内核数据结构定义
   - 软中断在内核中通过一个数据结构(通常是数组)来表示,其中每个条目代表一个软中断类型。Linux内核为每个处理器维护一个这样的数据结构。
   - 在`<linux/interrupt.h>头文件中预定义了一组软中断类型,例如网络相关的 NET_TX_SOFTIRQ` 和 NET_RX_SOFTIRQ,以及调度器相关的 SCHED_SOFTIRQ 等。
2. 初始化
   - 在系统启动时,内核会初始化软中断机制,包括预定义软中断向量的初始化。
3. 中断处理和软中断激活
   - 当硬件中断发生并被服务时,顶半部(Top Half)快速执行,并且在必要时通过调用特定的函数例如 raise_softirq 激活一个或多个软中断。
   - 激活软中断涉及到设置相应软中断的状态,通常是通过设置标志位来指示这个软中断需要被处理。
4. 软中断处理
   - 软中断处理可以在几种不同的上下文中执行。最常见的情形包括从中断上下文返回到用户态之前,以及内核检测到CPU空闲时。
   - 当内核准备处理软中断时,它会检查每个软中断的状态,并对设置了激活标志的软中断调用其注册的处理函数。
   - 这个处理函数是在软中断注册时指定的,是执行实际任务的代码,比如网络数据的接收和发送处理函数。
5. 并发和锁定
   - 由于软中断可以在多核系统中的任意CPU上执行,因此内核必须确保某一特定类型的软中断在同一时刻只能在一个CPU上运行。内核中实现了锁机制来管理这种并发。
   - 为了保证性能和避免死锁,软中断的执行过程中一般不能进行阻塞操作。
6. 性能优化
   - 内核会尝试尽可能高效地处理软中断,包括可能的负载均衡(将软中断工作分配给不同的CPU)以及“延迟处理”(如ksoftirqd守护线程)来降低软中断对实时任务的影响。
7. ksoftirqd守护线程
   - 对于每个CPU,内核都维护了一个名为ksoftirqd的内核线程。这个线程负责确保软中断得到处理,特别是当系统很忙且软中断无法及时处理时。
   - 这个线程的优先级很低,只有当系统的软中断负载较重时才会运行,以避免影响到更重要的任务。
综上所述,软中断是内核为了处理不适合在硬件中断上下文直接执行的任务而设计的一种轻量级机制。它们可以延迟执行并分担中断处理的负载,同时满足系统对实时性的需求。

三、内核抢占与软中断

Linux 内核自 2.6 版本开始,引入了主动抢占(Voluntary Preemption)和完全抢占(Preemptive Kernel)的概念,并且在随后的更新中继续提升了对抢占的支持。在 Linux 内核中,对抢占的支持可以通过内核配置选项进行调整。
有以下几种内核抢占模型:
1. 无抢占内核(No Preemption):这是传统的 Linux 内核模型,用于需要非常高稳定性和响应时间不是首要考虑的服务器环境。
2. 自愿抢占(Voluntary Preemption, CONFIG_PREEMPT_VOLUNTARY):这种模式在内核中插入许多显式的抢占点,以便提高系统的响应性。这种模式适合大多数台式机和笔记本电脑使用,因为它在系统响应性和稳定性之间提供了一个很好的折衷。
3. 抢占式内核(Preemptive Kernel, CONFIG_PREEMPT):这个选项是为了最大程度地降低内核代码的延迟,特别适合需要高响应性的桌面和嵌入式系统,但可能会牺牲一些稳定性。
4. 实时内核(Real-time Kernel, CONFIG_PREEMPT_RT):这是通过实时补丁(PREEMPT_RT)获得的 Linux 内核变种,可以为需要实时响应的系统提供预测性的、低延迟的行为。适用于工业、科研、音视频处理等对实时性要求很高的场合。
发行版维护者或用户可以根据自己的需求选择适当的抢占模式。

内核抢占(Kernel Preemption)
内核抢占是指操作系统允许一个内核模式的进程被另一个更高优先级的进程抢占。这通常发生在以下几种情况:
1. 当一个进程完成了它的时间片。
2. 当更高优先级的进程准备运行时,例如,从睡眠状态被唤醒。
3. 一些同步机制可能会导致当前运行的进程放弃处理器。
在没有抢占的内核中,一旦进程进入内核模式执行系统调用或其他内核任务,它会一直运行,直到主动放弃CPU控制权。这可能会导致系统响应变慢,因为高优先级任务可能需要等待低优先级任务完成其内核模式下的工作。内核抢占能够提高系统的响应性,特别是在多任务环境下。
软中断(Softirqs)
软中断是Linux内核中处理中断相关工作的一种机制。它们是相对硬件中断的概念(在旧一些的资料可能会碰到"硬中断"这一英文直译术语,但通常现在更倾向于直接使用英文"hardware interrupt");硬件中断是由CPU外部设备触发的,是中断处理的第一阶段。
当硬件中断发生时,CPU会立刻暂停当前执行的任务,转而执行一个非常短小的中断服务程序(Interrupt Service Routine, ISR),ISR的任务是快速地响应中断,执行一些紧急处理,然后标记软中断去完成剩余工作。这使得中断服务程序可以快速结束,CPU可以尽快恢复其他任务的执行。软中断处理则是延后执行的,可以批量处理一些工作,或者在处理器比较空闲的时候再执行。
通过将中断处理分为两个阶段,Linux内核能够提供快速响应硬件中断的同时,又能将耗时的处理工作推迟到软中断中去完成,以减少对系统性能的影响。软中断可以被内核抢占,但它们自己之间不会抢占彼此,因此可以保证一定程度的执行顺序。

在早期的 Linux 内核中,内核是非抢占的,意味着一旦一个进程进入内核模式执行系统调用或者内核代码,它会一直运行到返回到用户模式,除非它自己放弃 CPU。在这种模式下,一个正在执行的内核路径不会被另一个更高优先级的任务抢占。
随着 Linux 内核的发展,为了提高系统的响应性和实时性,引入了「抢占式内核」(PREEMPT) 功能。从 2.6 版本开始,Linux 内核提供了可配置的抢占模型。抢占式内核允许在执行内核代码时(不包括关键区,即临界区和中断处理程序),根据需要将 CPU 让给更高优先级的任务,这在多任务系统中尤为重要,能够减少任务响应时间,提高系统的实时性。
对于抢占式内核,一旦有更高优先级的任务需要运行,当前任务可以在内核态被抢占,只要它们不在临界区内。这种特性对于需要快速响应外部事件的实时操作系统尤为重要。
关于软中断(softirq)是 Linux 内核中一种底层的机制,用来处理非即时的中断处理工作。它们通常发生在两种情况下:
1. 硬件中断的底半部(bottom half)处理:当硬件产生中断时,中断处理被分为两部分。上半部(顶半部,top half)是指那些必须立即执行的处理工作,由硬件中断直接触发并立即执行;下半部是指可以推迟处理的、不那么急迫的工作,通常由软中断来处理。
2. 在内核中需要异步处理的其他情况。
软中断可以被抢占,它们的执行可以在任何非临界的内核上下文中发生,但是软中断本身不会主动放弃处理器控制权。这意味着一旦软中断开始执行,它们会运行到完成,除非它们被硬中断或者硬件中断的上半部抢占。这样设计是为了避免复杂的锁依赖和避免软中断处理被无限期地推迟。
总结来说,最新的 Linux 内核提供了抢占式内核的功能,可以通过配置选项开启或关闭。而软中断作为内核中的一种机制,用于处理那些可以延后而非即时处理的工作,与内核抢占机制相辅相成,共同提高系统的效率和响应速度。

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

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

相关文章

ChatGPT :确定性AI源自于确定性数据

ChatGPT 幻觉 大模型实际应用落地过程中&#xff0c;会遇到幻觉&#xff08;Hallucination&#xff09;问题。对于语言模型而言&#xff0c;当生成的文本语法正确流畅&#xff0c;但不遵循原文&#xff08;Faithfulness&#xff09;&#xff0c;或不符合事实&#xff08;Factua…

Linux下进程的调度与切换

&#x1f30e;进程的调度与切换 文章目录&#xff1a; 进程的调度与切换 进程切换 进程调度       活动状态进程队列       位图判断       过期队列 总结 前言&#xff1a; 在Linux操作系统中&#xff0c;进程的调度与切换是操作系统核心功能之一&#xff…

【LabVIEW FPGA入门】流水线

LabVIEW中流水线 在当今多核处理器和多线程应用程序的世界中&#xff0c;程序员在开发应用程序时需要不断思考如何最好地利用尖端 CPU 的强大功能。尽管用传统的基于文本的语言构建并行代码可能难以编程和可视化&#xff0c;但 NI LabVIEW 等图形开发环境越来越多地允许工程师和…

学习笔记 | 微信小程序项目day02

今日学习内容 安装uni-ui跟uni-helper/uni-ui-types配置pinia持久化请求工具类的拦截器请求工具类的请求函数 安装uni-ui跟uni-helper/uni-ui-types npm install -g cnpm --registryhttps://registry.npmmirror.com npm set registry https://registry.npmmirror.com npm i …

电脑充电器能充手机吗?如何给手机充电?

电脑充电器可以给手机充电吗&#xff1f; 电脑充电器可以给手机充电&#xff0c;但前提是电脑充电器的功率输出与手机的功率匹配且接口匹配。 假设电脑充电器的输出功率为5V/2A&#xff0c;手机也支持5V/2A的输入功率。 只要接口匹配&#xff0c;就可以使用电脑充电器给手机充…

2024智慧农场系统微信小程序前端如何上传以及配置

2024智慧农场系统微信小程序前端如何上传以及配置 首先下载微信开发者工具 下载好以后打开&#xff0c;然后导入项目 前端修改&#xff1a;siteinfo.js 里面的域名信息 改完之后开始在微信开发者工具中开发工具中编译、上传、发布即可

vim | 介绍vim以及配置vimrc文件

好像熟练使用vim 是玩linux 必修课 当然&#xff0c;初代玩家能在vim 完成编辑 并保存已是入门了&#xff0c;想当初在大学的时候&#xff0c;死活转不过来&#xff0c;玩不过来&#xff0c;甚至有些恐惧 但后来&#xff0c;弄清楚原理&#xff0c;反倒觉得简简单单已是完美了。…

19. UE5 RPG使用GameplayEffect的Attribute Based Modifiers

前几篇文章我也说了GE的基础使用&#xff0c;但是&#xff0c;对一些属性的应用没有述说&#xff0c;后续&#xff0c;我将一点一点的将它们如何使用书写下来。 这一篇&#xff0c;主要就讲解一下Attribute Based Modifiers使用&#xff0c;先说一下它的应用场景&#xff0c;一…

C++ -- 多态

多态 1. 多态的概念 多态的概念&#xff1a;通俗来说&#xff0c;就是多种形态&#xff0c;具体点就是去完成某个行为&#xff0c;当不同的对象去完成时会产生出不同的状态。 2. 多态的定义及实现 2.1多态的构成条件 多态是在不同继承关系的类对象&#xff0c;去调用同一函…

实现界面跳转及注册界面编写(AndroidStudio)

目录 一、代码 二、最后效果 一、代码 1.先新建一个activity文件 2.注册界面的代码如下&#xff1a; <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:la…

Docker学习之数据管理(超详解析)

Docker存储资源类型&#xff1a; 用户在使用 Docker 的过程中&#xff0c;势必需要查看容器内应用产生的数据&#xff0c;或者需要将容器内数据进行备份&#xff0c;甚至多个容器之间进行数据共享&#xff0c;这必然会涉及到容器的数据管理&#xff1a; &#xff08;1&#xff…

Java代码基础算法练习-判断素数-2024.03.17

任务描述&#xff1a; 输入一个数x&#xff0c;判断它是否是素数。 提示&#xff1a;素数是只能被1和它本身整除的数&#xff0c;1不是素数。 任务要求&#xff1a; 代码示例&#xff1a; package march0317_0331;import java.util.Scanner;public class March0317 {public …

LeetCode 面试经典150题 55.跳跃游戏

题目&#xff1a; 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 思路…

django实现api接口

&#xff08;前期准备&#xff09;第一步&#xff1a;虚拟环境 在windows上使用virtualenvwrapper。 pip install virtualenvwrapper-win 接着&#xff0c;添加环境变量。 echo %WORKON_HOME% 接下来就是创建虚拟环境&#xff0c;假如创建myenv mkvirtualenv myenv 进入…

RabbitMQ——死信队列和延迟队列

文章目录 RabbitMQ——死信队列和延迟队列1、死信队列2、基于插件的延迟队列2.1、安装延迟队列插件2.2、代码实例 RabbitMQ——死信队列和延迟队列 1、死信队列 死信队列&#xff08;Dead Letter Queue&#xff0c;DLQ&#xff09;是 RabbitMQ 中的一种重要特性&#xff0c;用…

ChatGPT编程实现简易聊天工具

ChatGPT编程实现简易聊天工具 今天借助[[小蜜蜂]][https://zglg.work]网站的ChatGPT练习socket编程&#xff0c;实现一个简易聊天工具软件。 环境&#xff1a;Pycharm 2021 系统&#xff1a;Mac OS 向ChatGPT输入如下内容&#xff1a; ChatGPT收到后&#xff0c;根据返回结…

企业内部培训考试系统培训计划功能说明

培训计划是预设好的一套课程系列&#xff0c;包含课程和考试&#xff0c;分多个阶段&#xff0c;每完成一个阶段就会在学习地图上留下标记&#xff0c;让用户看到自己的努力成果&#xff0c;增强成就感&#xff0c;从而坚持完成课程。 企业内部培训考试系统中如何设置培训计划…

动态代理原理- JDK动态代理、CGLIB动态代理

概述&#xff1a;在不改变原有功能代码的前提下&#xff0c;能动态的实现方法的增强 JDK动态代理原理&#xff1a; 通过实现接口&#xff0c;获取到接口里面的所有方法通过Proxy创建代理实例通过反射机制&#xff0c;获取到一个一个的方法对象调用InvocationHandler接口中的in…

Python之Web开发中级教程----ubuntu中下载安装Postman

Python之Web开发中级教程----ubuntu中下载安装Postman PostMan 是一款功能强大的网页调试与发送网页 HTTP 请求的 Chrome 插件&#xff0c;可以直接去对我们写出来的路由和视图函数进行调试&#xff0c;作为后端程序员是必须要知道的一个工具。 查看ubuntu系统中是否已经安装了…

Java BIO (同步阻塞型IO) 内容上集

IO简介 一、前言 在java软件设计开发中&#xff0c;通信框架是不可避免的&#xff0c;我们在不同的系统或者这不同的进程之间进行数据交互&#xff0c;或者在高并发的场景下需要用到网络通信相关的技术&#xff0c;从上节课的例子当中我们看出同步阻塞式的IO通信(BIO)效率过于…