当前位置: 首页 > news >正文

Linux内核中的Completion机制:同步等待的艺术

Linux内核中的Completion机制:同步等待的艺术

作为一名深耕操作系统和嵌入式开发的工程师,我对Linux内核中的Completion机制有着深入的理解。Completion是一种轻量级的同步原语,用于一个线程等待另一个线程完成某个操作。

Completion的基本概念

Completion机制的核心思想是:

  • 单次信号:一旦完成,所有等待者都会被唤醒
  • 无需锁:不需要额外的锁来保护状态
  • 内存效率高:只需要一个结构体即可实现

Completion的核心API

1. 初始化和销毁

// 静态初始化 DECLARE_COMPLETION(my_completion); // 动态初始化 struct completion my_completion; init_completion(&my_completion); // 重新初始化(可重复使用) reinit_completion(&my_completion);

2. 等待完成

// 无限期等待 wait_for_completion(&my_completion); // 带超时等待 long timeout = wait_for_completion_timeout(&my_completion, msecs_to_jiffies(1000)); if (timeout == 0) { // 超时 } // 可中断等待 int ret = wait_for_completion_interruptible(&my_completion); if (ret == -ERESTARTSYS) { // 被信号中断 } // 可中断且带超时 int ret = wait_for_completion_interruptible_timeout(&my_completion, msecs_to_jiffies(1000));

3. 完成信号

// 唤醒一个等待者 complete(&my_completion); // 唤醒所有等待者 complete_all(&my_completion);

Completion的实现原理

struct completion { unsigned int done; wait_queue_head_t wait; }; // 等待实现 void wait_for_completion(struct completion *x) { wait_queue_t wait; spin_lock_irq(&x->wait.lock); if (!x->done) { // 添加到等待队列 __add_wait_queue_tail(&x->wait, &wait); // 睡眠等待 do_wait(); } else { x->done--; } spin_unlock_irq(&x->wait.lock); } // 完成信号实现 void complete(struct completion *x) { unsigned long flags; spin_lock_irqsave(&x->wait.lock, flags); x->done++; __wake_up_locked(&x->wait, TASK_NORMAL, 1); spin_unlock_irqrestore(&x->wait.lock, flags); }

使用场景

1. 模块加载等待

static struct completion module_loaded; static int __init my_module_init(void) { init_completion(&module_loaded); // 创建工作线程 kthread_run(worker_thread, NULL, "my_worker"); // 等待工作线程初始化完成 wait_for_completion(&module_loaded); return 0; } static int worker_thread(void *data) { // 初始化工作 do_initialization(); // 通知初始化完成 complete(&module_loaded); // 继续执行 while (!kthread_should_stop()) { do_work(); } return 0; }

2. 异步I/O完成通知

struct async_io { struct completion done; int result; }; int async_read(struct file *file, void *buf, size_t count) { struct async_io io; init_completion(&io.done); // 提交异步I/O请求 submit_async_request(file, buf, count, io_complete_callback, &io); // 等待I/O完成 wait_for_completion(&io.done); return io.result; } void io_complete_callback(void *private, int result) { struct async_io *io = private; io->result = result; complete(&io->done); }

3. 多阶段初始化

struct init_stage { struct completion stage1_done; struct completion stage2_done; struct completion stage3_done; }; void multi_stage_init(struct init_stage *stage) { init_completion(&stage->stage1_done); init_completion(&stage->stage2_done); init_completion(&stage->stage3_done); // 启动阶段1 kthread_run(stage1_worker, stage, "stage1"); wait_for_completion(&stage->stage1_done); // 启动阶段2 kthread_run(stage2_worker, stage, "stage2"); wait_for_completion(&stage->stage2_done); // 启动阶段3 kthread_run(stage3_worker, stage, "stage3"); wait_for_completion(&stage->stage3_done); }

与信号量和锁的对比

特性Completion信号量互斥锁
用途一次性事件资源计数互斥访问
可重复使用是(需reinit)
等待者数量多个多个多个
典型场景初始化完成资源池临界区保护

性能优化建议

  1. 避免在热路径使用:Completion适合初始化等冷路径
  2. 合理设置超时:防止无限期等待
  3. 处理中断情况:使用可中断版本处理信号
  4. 注意完成顺序:确保complete在wait之后调用

总结

Completion是Linux内核中简洁高效的同步机制,特别适合初始化完成通知、异步操作等待等场景。作为嵌入式开发者,合理使用Completion可以简化同步逻辑,提高代码可读性。

http://www.jsqmd.com/news/593323/

相关文章:

  • 三菱电梯保密资料解析与代码分析
  • python codecs
  • -python-langchain框架(3-6-pdf文件分页加载 )
  • 从零搭建TRACE32硬件调试环境:集成CANoe实现CANFD报文收发实战
  • 基于Vivado工程的FPGA多通道以太网实时同步采集系统——AD7606八通道同步采集与UD...
  • 智能工具赋能游戏体验:Snap Hutao开源游戏助手全面解析
  • 熵,PSI,IV在机器学习中的应用
  • Linux内核中的Per-CPU变量:无锁并发编程
  • 2026年全链路性能测试方案选型与实施指南
  • python zipfile
  • COMSOL合并BIC:能带计算、Q因子计算、远场偏振投影及录屏指导
  • 游戏化学习与编程实战:CodeCombat让编程学习像玩游戏一样简单
  • 抖音无水印视频批量下载全攻略:从痛点解决到高效管理
  • Netty 线程模型
  • 2026年3月实测!GEO优化厂家产品性能大揭秘,专业的GEO优化口碑推荐技术领航者深度解析 - 品牌推荐师
  • 如何用OpCore-Simplify在30分钟内完成黑苹果配置:自动化OpenCore EFI工具终极指南
  • 飞轮储能 背靠背变流器 充放电控制 并网控制 matlab/simulink仿真模型 包括机侧...
  • 4步解决Windows Defender管控难题:技术用户的系统防护配置指南
  • 第7章 运算符-7.2 赋值运算符
  • MaaYuan自动化辅助工具高效配置避坑指南:零基础入门三步完成环境部署
  • CQUPT 2025级 数据科学与大数据技术英才班 周测#02
  • Java 开发者零成本构建 RAG 知识库:Spring AI Alibaba + Ollama 搭建本地 RAG 知识库
  • 5步快速上手:用Ryujinx在PC上完美运行Switch游戏终极指南
  • Node.js——dns模块
  • 第26课:Qt 接管 MISC、input 与定时器,把事件流和倒计时界面一起跑通
  • NSudo完全指南:轻松获取Windows最高权限的5种方法
  • 告别B站资源无法保存的烦恼:BiliTools跨平台工具箱完整使用指南
  • nacos
  • 第27课:Qt 看门狗倒计时实战,学会让界面节奏和系统守护对齐
  • 从安装到首次提交,在快马平台实战演练中掌握git核心工作流