news 2026/9/2 15:09:31

Linux驱动开发八股文:工作队列(Workqueue)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux驱动开发八股文:工作队列(Workqueue)

📚 Linux 驱动开发笔记:工作队列 (Workqueue)

一、 核心定义

工作队列是 Linux 内核中断下半部(Bottom Half)的一种重要机制。它允许你将耗时的、需要等待资源或可能导致休眠的任务,从中断处理函数(ISR)中推迟到稍后的进程上下文中执行。

  • 关键特性:运行于进程上下文,可以休眠
  • 执行主体:内核线程(如kworker/0:2)。

二、 为什么需要工作队列? (对比 Tasklet)

在内核中,中断下半部主要有两种选择,它们的区别在于“执行环境”:

特性Tasklet工作队列 (Workqueue)
执行上下文中断(软中断)上下文进程上下文
能否休眠绝不可以(会系统崩溃)可以(如使用msleep
访问用户空间不可以不可以(虽然在进程上下文,但没有用户页表)
优先级极高,仅次于硬中断较低,由调度器决定
代表身份借用当前进程的“皮”拥有独立的内核线程 (kworker)

三、 工作队列的运作机制

  1. 提交任务:驱动在 ISR 中通过schedule_work函数提交一个work_struct
  2. 排队等待:该任务进入系统默认的工作队列链表。
  3. 唤醒线程:内核唤醒对应的内核线程(kworker)。
  4. 执行任务kworker线程从链表中取出任务,调用你编写的处理函数。
  5. 结束/调度:处理函数完成后,kworker线程继续处理下一个任务,或者进入睡眠。

四、 核心 API 与编程步骤

1. 定义工作结构体与处理函数

处理函数的参数是结构体本身,通常通过container_of获取私有数据。

struct work_struct my_work; void my_work_func(struct work_struct *work) { // 这里可以休眠! // printk("current->comm: %s, pid: %d\n", current->comm, current->pid); }
2. 初始化 (Init)

probe函数中完成,将函数指针绑定到结构体。

// 动态初始化 INIT_WORK(&gpio_key->work, my_work_func); // 或者静态定义 // DECLARE_WORK(name, function);
3. 调度 (Schedule)

在中断上半部(ISR)中调用,触发异步执行。

static irqreturn_t gpio_key_isr(int irq, void *dev_id) { schedule_work(&gpio_key->work); // 只是挂入队列,不阻塞 return IRQ_HANDLED; }

五、 实验现象深度解析

根据实验日志:

[165328.733643] {WORK_FUNC:}the process is kworker/0:2, its pid is 1722
  1. 身份证明current->commkworker/0:2,证明了工作队列不再是“借用”别人的身份,而是由内核专属的“工人”线程在干活。
  2. PID 1722:这是一个真实的进程 ID。在 Linux 中,凡是有 PID 的都能被调度器控制,这就是它为什么可以休眠的根本原因。
  3. 时序关系:日志中TASKLET总是先于WORK_FUNC打印。这是因为 Tasklet 优先级更高,在中断返回的瞬间执行;而 Workqueue 需要等待调度器切换到kworker线程,存在毫秒级的调度延迟。

六、 注意事项与避坑指南

  1. 顺序阻塞:默认的工作队列由同一个kworker线程依序处理。如果你在一个 Work 函数里写了while(1)或休眠太久,会堵塞同一个队列里的其他工作
  2. 重入性:如果在 Work 还没执行完时又发生了中断并schedule_work,内核通常不会重复启动同一个 Work 实例,它会等待当前运行的结束后再决定是否再次触发。
  3. API 演进:4.x 以后内核引入了CMWQ (Concurrency Managed Workqueue),它能更聪明地在多核之间分配任务,避免单个耗时任务卡死整个 CPU 的工作队列。

七、 总结:何时选择工作队列?

  • 任务很重(如:读取 1MB 的 Flash 数据)。
  • 需要等待(如:等待某个信号量、互斥锁)。
  • 需要延时(如:逻辑要求按键按下后等待 100ms 再读取)。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/2 22:29:21

搞定NPU推理加速实战

💓 博客主页:借口的CSDN主页 ⏩ 文章专栏:《热点资讯》 NPU推理加速实战:突破边缘智能的效率瓶颈目录NPU推理加速实战:突破边缘智能的效率瓶颈 引言:为什么NPU推理加速是AI落地的生死线 一、现在时&#xf…

作者头像 李华
网站建设 2026/9/2 23:15:37

强烈安利10个AI论文软件,MBA毕业论文轻松搞定!

强烈安利10个AI论文软件,MBA毕业论文轻松搞定! AI 工具如何让论文写作更高效? 在当前的学术环境中,MBA 学生和研究者们正面临越来越多的挑战。从选题到撰写,再到查重与修改,每一个环节都可能成为耗时费力的…

作者头像 李华
网站建设 2026/9/2 22:29:04

吐血推荐!10款AI论文网站测评:本科生毕业论文必备

吐血推荐!10款AI论文网站测评:本科生毕业论文必备 2026年AI论文写作工具测评:为何值得一看 随着人工智能技术的不断进步,AI论文写作工具逐渐成为本科生撰写毕业论文的重要辅助。然而,市场上工具繁多,功能参…

作者头像 李华
网站建设 2026/9/2 1:11:09

Doris与Trino集成:统一SQL大数据查询引擎

Doris与Trino集成:统一SQL大数据查询引擎 关键词:Doris、Trino、SQL查询引擎、大数据分析、数据仓库、联邦查询、OLAP 摘要:本文深入探讨了Apache Doris与Trino两大流行SQL查询引擎的集成方案,旨在构建统一的大数据查询平台。文章首先分析了两者的架构特点和互补优势,然后…

作者头像 李华
网站建设 2026/9/2 19:58:10

Hive数据血缘分析:大数据治理的关键技术

Hive数据血缘分析:大数据治理的关键技术 一、引言:为什么数据血缘是大数据治理的"生命线"? 1.1 一个真实的痛点场景 假设你是一家电商公司的数据分析师,今天早上刚到公司就收到业务部门的紧急投诉:“昨天的用…

作者头像 李华
网站建设 2026/9/2 2:10:17

STM32调试技巧:Keil MDK实用操作指南

STM32调试进阶:用Keil MDK打造高效开发闭环你有没有遇到过这样的场景?程序跑着跑着突然死机,串口毫无输出;ADC采样值莫名其妙跳变;某个全局变量在中断里被悄悄改写却找不到源头……面对这些问题,靠“加打印…

作者头像 李华