news 2026/2/18 23:15: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/2/18 17:53:59

【安全测试】1_安全测试体系 _安全测试介绍

文章目录一、安全测试介绍1.1 安全测试与传统测试的区别1.2 安全测试与渗透测试的区别二、安全测试常用方法三、安全测试维度四、安全测试点一、安全测试介绍 安全测试就是发现软件安全漏洞的过程,旨在保护软件系统的数据与功能。 安全测试以破坏系统的安全策略为…

作者头像 李华
网站建设 2026/2/16 13:21:30

贸发局主办全球最大一站式珠宝商贸平台

荟萃环球珍品 新设硬足金展馆展现黄金崭新技术由香港贸易发展局(香港贸发局)主办的全球最大一站式珠宝商贸平台,将于3月初以“两展两地”的成功模式揭幕。第12届香港国际钻石、宝石及珍珠展于3月2至6日在亚洲国际博览馆举行,展出…

作者头像 李华
网站建设 2026/2/17 22:38:52

去年的国自然本子修改之后可以今年再提交吗?

国自然评审意见公布后,不少科研同行都会陷入困境:拿到修改意见无从下手,去年未中的本子改来改去仍抓不住重点,专家点评言简意赅却藏着“潜台词”,解读不到位就会南辕北辙。作为过来人,我深知国自然修改比初…

作者头像 李华
网站建设 2026/2/16 13:22:20

DeerFlow镜像免配置:预置Chrome Headless环境保障稳定网页渲染

DeerFlow镜像免配置:预置Chrome Headless环境保障稳定网页渲染 1. 引言:告别网页渲染的烦恼 你有没有遇到过这样的场景?好不容易部署好一个AI研究工具,想让它帮你搜索资料、分析网页内容,结果第一步就卡住了——网页…

作者头像 李华