一、基本概念1. 等待队列Wait Queue定义等待队列是内核通用的进程阻塞/唤醒机制用于让进程等待某个任意条件如资源可用、信号到达、事件触发。核心结构struct wait_queue_head_t { spinlock_t lock; // 保护队列的自旋锁 struct list_head head; // 等待进程的链表头 }; struct wait_queue_entry { struct task_struct *task; // 等待的进程 struct list_head entry; // 链表节点 // 可选的回调函数如poll };关键操作初始化init_waitqueue_head(wait_queue_head_t *q)添加等待进程add_wait_queue(q, entry)将进程加入队列设置进程状态set_current_state(TASK_UNINTERRUPTIBLE/TASK_INTERRUPTIBLE)标记为阻塞调度schedule()主动让出CPU唤醒wake_up(q)唤醒队列中所有符合条件的进程、wake_up_interruptible(q)仅唤醒可中断进程特点灵活支持复杂条件判断如循环检查变量状态适用于生产者-消费者、多条件等待等场景。2. 完成量Completion定义完成量是基于等待队列的简化封装专门用于等待单一事件完成如“操作已结束”“任务已完成”。核心结构struct completion { unsigned int done; // 事件完成计数0表示未完成 wait_queue_head_t wait; // 底层等待队列继承自wait queue };关键操作初始化init_completion(struct completion *x)done0或DECLARE_COMPLETION(name)静态初始化等待事件wait_for_completion(struct completion *x)阻塞直到done≠0唤醒事件complete(struct completion *x)done唤醒1个等待进程、complete_all(struct completion *x)doneUINT_MAX唤醒所有等待进程特点接口极简仅需“初始化-等待-唤醒”三步适用于单次事件同步如线程间通知“任务完成”。二、核心区别维度​等待队列Wait Queue​完成量Completion​抽象层次​底层通用机制高层封装基于wait queue用途​等待任意复杂条件如缓冲区非空、信号到达等待单一事件完成如“操作已结束”接口复杂度​需手动管理队列、进程状态、唤醒逻辑提供init/complete/wait简单接口唤醒粒度​支持唤醒单个wake_up_nr或所有wake_up进程支持唤醒1个complete或所有complete_all进程状态管理​需显式设置进程状态如TASK_UNINTERRUPTIBLE内部自动处理状态默认用TASK_UNINTERRUPTIBLE重复使用​可重复添加/删除进程队列长期有效完成后需init_completion重置才能再次使用错误处理​可通过wake_up_interruptible响应信号返回错误码wait_for_completion被信号中断时返回-ERESTARTSYS三、适用场景举例1. 用完成量Completion的场景单次事件通知如“DMA传输完成”“编码线程处理完一帧”。例视频采集线程采集到一帧后用complete()通知编码线程编码线程用wait_for_completion()等待。struct completion frame_done; init_completion(frame_done); // 采集线程 capture_frame(); complete(frame_done); // 通知编码线程“帧已就绪” // 编码线程 wait_for_completion(frame_done); // 等待帧就绪 encode_frame();简单线程同步如主线程等待子线程初始化完成。2. 用等待队列Wait Queue的场景复杂条件等待如“缓冲区有数据且未溢出”生产者-消费者模型。例流媒体传输线程等待“发送缓冲区有数据”采集线程填充数据后唤醒队列。wait_queue_head_t send_wait; init_waitqueue_head(send_wait); char send_buf[1024]; int buf_len 0; // 传输线程消费者 while (1) { wait_event(send_wait, buf_len 0); // 等待缓冲区有数据 send_data(send_buf, buf_len); buf_len 0; } // 采集线程生产者 buf_len capture_to_buf(send_buf); if (buf_len 0) wake_up(send_wait); // 唤醒传输线程多条件等待如同时等待“网络就绪”和“设备初始化完成”。四、总结完成量是简化的事件同步工具适合“等待某事发生”的单次场景代码简洁、开销小。等待队列是通用的条件等待工具适合“等待复杂条件满足”的场景灵活性高但需手动管理。在流媒体开发中若只需通知“某操作完成”如编码结束优先用完成量若需等待“多条件组合”如缓冲区数据网络带宽足够则用等待队列。两者均基于内核同步原语理解其差异能帮助于更高效地解决流媒体 pipeline 中的同步问题如采集-编码-显示的时序协调。