少于 1 分钟阅读 次阅读

一、核心概念一句话定义

  • 中断处理程序(Interrupt Handler):由硬件中断触发、立即执行的紧急响应程序,用于处理对时间敏感、与硬件相关的关键操作。
  • 上半部(Top Half):指中断处理程序的前半部分,在中断发生时立即执行,通常处理硬件应答、数据拷贝等严格时限任务,且执行时中断会被屏蔽。
  • 下半部(Bottom Half):指中断处理流程中推迟执行的部分,用于处理上半部未完成、允许稍后执行的、非紧急的后续任务,在适当的时机以开中断方式运行。

二、为何要分上下两半?

将中断处理分为上下两半,主要是为了解决速度与工作量之间的矛盾。中断处理程序自身有四大局限:

  1. 异步执行,可能打断关键代码,因此必须尽量快。
  2. 执行时屏蔽同级或全部中断,硬件通信会受影响,因此必须尽量短。
  3. 常需操作硬件,有时效要求。
  4. 不在进程上下文运行,不能阻塞。

如果所有工作都在中断处理程序中完成,系统响应速度和吞吐量会严重下降。因此,Linux 采取了“紧急任务马上做,不急任务推后做”的策略:上半部快速响应硬件,完成关键操作;下半部在系统更空闲时处理其余任务,比如解析网络数据包、更新数据结构等。

三、上半部与下半部的分工原则

  • 上半部负责:

    • 对时间敏感的操作(如应答硬件、防止缓存溢出)。
    • 必须与硬件交互的任务(如从网卡拷贝数据到内存)。
    • 需要保证不被其他中断(特别是同类型中断)打断的任务。
  • 下半部负责:

    • 所有不紧急、可延迟处理的任务。
    • 对时间不敏感的数据处理、逻辑运算等。

以网卡接收数据为例:

  • 上半部:硬件中断触发 → 立即应答网卡 → 将数据包快速拷贝到内存(防止网卡缓存溢出)。
  • 下半部:数据包已存入内存后,在合适时机(如稍后开中断执行)对数据包进行协议解析、传递给应用程序等后续处理。

这样的分工既保证了硬件的实时响应,又避免了长时间屏蔽中断导致系统失去响应。

四、下半部机制的演变

Linux 提供了多种实现下半部的机制,其发展历程如表所示:

机制 状态 特点
BH(Bottom Half) 2.5 中去除 最早的 32 个静态下半部链表,全局同步,简单但性能差
任务队列(Task Queues) 2.5 中去除 用队列管理推后执行的函数,比 BH 灵活但仍不足
软中断(Softirq) 从 2.3 引入 静态注册、高性能,可在多处理器上并发执行,适用于网络等高性能场景
tasklet 从 2.3 引入 基于软中断实现,动态注册,同类型不能并发,是性能与易用性的平衡
工作队列(Work Queues) 从 2.5 引入 将工作推后到进程上下文中执行,可以睡眠和阻塞

目前,软中断、tasklet 和工作队列是主流的下半部实现机制:

  • 软中断:追求极致性能,但需小心并发控制。
  • tasklet:适合大多数场景,易于使用。
  • 工作队列:适合需要睡眠或长时间处理的任务。

留下评论