news 2026/4/16 12:10:07

Linux内核中--中断顶半部与底半部

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux内核中--中断顶半部与底半部

一、中断处理

当中断发生时,CPU 会立即暂停当前执行流,跳转到对应的中断服务例程(ISR, Interrupt Service Routine)。这个 ISR 就是顶半部。它运行在中断上下文(interrupt context)中,具有以下关键限制:

  1. 不可睡眠(Non-sleepable)
    不能调用任何可能导致阻塞的函数(如mutex_lock(),kmalloc(GFP_KERNEL),ssleep()等),否则会导致内核崩溃或死锁。

  2. 关中断(Interrupts disabled)
    在执行期间,本地 CPU 的中断通常被屏蔽(至少是该 IRQ 线),以保证原子性。若顶半部执行时间过长,将导致:

    • 其他中断无法及时响应(可能丢失)
    • 系统整体延迟升高,出现“卡顿”
  3. 无进程上下文(No process context)
    无法访问用户空间,也不能被调度器抢占。

二、分层模型的思想

顶半部(Top Half):快进快出,绝不拖延。

底半部(Bottom Half):在安全、宽松的上下文中完成所有非紧急但必要的后续处理,可睡眠、可被抢占、中断已开启,不影响系统实时性。

进程上下文:进程相关代码、open、read、write。 workqueue 可以休眠、阻塞,可以被调度
中断上下文:中断处理相关代码、中断服务程序、软中断、tasklet 不能休眠、阻塞,不能被调度

三、底半部实现机制

1. Tasklet(基于 SoftIRQ)
上下文:软中断(SoftIRQ)上下文
特点:

  • 不可睡眠(同顶半部)
  • 同一 tasklet 实例严格串行执行(自动防并发)
  • 执行优先级高,紧随硬中断之后

适用场景:

  • 快速、简单、无需睡眠的任务
  • 对延迟极度敏感的操作(如网络包接收的初步处理)
DECLARE_TASKLET(my_tasklet, handler_func, data); tasklet_schedule(&my_tasklet); // 在顶半部调度

2.Workqueue(工作队列)
上下文:内核线程(kworker)上下文 → 进程上下文
特点:

  • 可以睡眠(最大优势!)
  • 支持并发(不同 work 可在多 CPU 并行)
  • 延迟略高于 tasklet(需线程调度)

适用场景:

  • 需要睡眠的操作(如 msleep() 去抖动)
  • 耗时较长的任务(如文件 I/O、复杂计算)
INIT_WORK(&my_work, work_handler); schedule_work(&my_work); // 在顶半部调度

3.SoftIRQ(软中断,内核内部使用)
上下文:软中断上下文
特点:
性能极高,但需自行处理 SMP 并发
仅用于内核核心子系统(如网络、块设备)

特性TaskletWorkqueueSoftIRQ
上下文软中断进程(内核线程)软中断
可否睡眠不可可以不可
并发性同一实例串行多 work 可并行需自行同步
执行延迟极低中等极低
适用对象驱动/模块驱动/模块内核核心子系统

四、代码对比

共同的顶半部:key_irq_handler

static irqreturn_t key_irq_handler(int irq, void * dev) { int arg = *(int *)dev; if(100 != arg) return IRQ_NONE; // 核心调度逻辑 schedule_work(&work); // Workqueue版本 // tasklet_schedule(&tsk); // Tasklet版本 printk("irq = %d dev = %d\n", irq, arg); return IRQ_HANDLED; }

底半部一:工作队列 (Workqueue)

初始化

// 在 probe 函数中 INIT_WORK(&work, key_work_func);

底半部处理函数

static void key_work_func(struct work_struct *work) { ssleep(1); // 模拟一个耗时1秒的操作 condition = 1; wake_up_interruptible(&wq); printk("key_work_func ..\n"); }

关键特性:

  • 运行上下文:工作队列在内核线程(kworker)中执行。这意味着它运行在进程上下文中。
  • 可睡眠:因为是进程上下文,所以可以安全地调用可能导致睡眠的函数,例如这里的 ssleep(1)。这是工作队列相对于Tasklet的最大优势。
  • 并发性:不同工作队列之间可以并发执行。同一个工作项在同一时间只会被一个CPU执行,但不同的工作项可以在多个CPU上并行处理。

底半部二:Tasklet

初始化

// 在 probe 函数中 tasklet_init(&tsk, key_tasklet_handler, 100);

底半部处理函数

static void key_tasklet_handler(unsigned long arg) { condition = 1; wake_up_interruptible(&wq); printk("key_tasklet_handler arg = %ld\n", arg); }

关键特性:

  • 运行上下文:Tasklet在软中断(SoftIRQ)上下文中执行。
  • 不可睡眠:软中断上下文和中断上下文一样,不能被抢占,也不能睡眠。任何可能导致睡眠的调用都是非法的,并可能导致系统崩溃。
  • 串行化:同一个Tasklet在同一时间只能在一个CPU上运行,内核会保证其不会并发执行,简化了同步问题。但不同类型的Tasklet之间可以并发。

五、总结

  • 顶半部运行在中断上下文,必须快速、无阻塞,仅完成最小必要操作(如清中断、调度底半部);
  • 底半部在更安全的上下文(如软中断或内核线程)中执行耗时任务,其中 Workqueue 可睡眠、更灵活,是现代驱动的首选,而 Tasklet 适用于快速、不可睡眠的场景。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/15 18:30:40

爬虫?先看网站的robots.txt

文章目录robots.txt 是什么以zoopla为例分析1)robots.txt 的基本读法(先建立规则脑图)2)你这份 robots.txt:逐段(逐行簇)解释A. 文件开头的 ASCII 画B. 第一段:通用规则(…

作者头像 李华
网站建设 2026/4/11 13:23:21

标签与过滤器的动态交互

在网页设计中,如何通过点击标签来动态改变页面元素的状态是一个常见但有趣的问题。今天我们将探讨如何利用jQuery实现一个简单的标签点击效果,使得当标签被激活时,相关的过滤器会改变颜色,并在标签失活时恢复原状。 背景介绍 假设我们有一个博客系统,其中有多个标签(ta…

作者头像 李华
网站建设 2026/3/24 16:32:20

Corpay Cross-Border延长与澳大利亚橄榄球协会的独家合作关系

提供跨境支付和外汇风险管理解决方案全球领先的企业支付公司Corpay, Inc.* (NYSE: CPAY)今日宣布,其跨境业务已签署多年协议,延长与澳大利亚橄榄球协会成功且独家的合作关系,继续担任官方外汇(FX)支付合作伙伴。作为此次延长协议的一部分&…

作者头像 李华
网站建设 2026/4/16 4:42:36

零基础玩转Janus-Pro-7B:手把手教你实现文生图与图像分析

零基础玩转Janus-Pro-7B:手把手教你实现文生图与图像分析 1. 这个模型到底能做什么?先看真实效果 你可能已经听说过“多模态”这个词,但Janus-Pro-7B不是概念炒作,而是一个真正能把文字和图片打通的实用工具。它不像有些模型只能…

作者头像 李华
网站建设 2026/4/12 10:07:17

OFA图像描述模型Docker部署教程:从安装到API调用

OFA图像描述模型Docker部署教程:从安装到API调用 1. 引言 你是否曾经遇到过这样的场景:需要为大量图片自动生成文字描述,但手动标注既耗时又费力?或者想要为视障人士开发一个图像识别辅助工具,却不知道从何入手&…

作者头像 李华
网站建设 2026/4/1 8:18:20

OFA图像语义蕴含模型实战教程:与CLIP/ViLT模型效果对比评测指南

OFA图像语义蕴含模型实战教程:与CLIP/ViLT模型效果对比评测指南 1. 镜像简介与环境配置 今天我们来深入体验OFA图像语义蕴含模型的强大能力,并通过实际对比测试看看它在多模态理解任务中的表现。这个镜像已经为你准备好了完整的环境,基于Li…

作者头像 李华