深入理解 `rt_completion` —— 一次性同步机制的正确使用姿势

【RT-Thread】深入理解 rt_completion —— 一次性同步机制的正确使用姿势

作者:shenyang
时间:2025年6月
标签:RT-Thread / 多线程同步 / 信号机制 / 嵌入式系统


一、前言

在 RT-Thread 系统中,rt_completion 是一种轻量级的线程同步机制,用于线程之间的一次性完成通知
很多开发者在刚接触它时,会误以为它与信号量 rt_sem 类似,可以重复使用、积累事件,这种误解往往导致程序出现“莫名其妙的死等”或“事件丢失”的问题。

本文将结合一个形象的**“步枪上弹→瞄准射击”的类比,彻底讲清楚 rt_completion使用场景、限制与正确姿势**。


二、rt_completion 是什么?

它的核心作用是:

用于某个线程等待另一个线程或中断完成一个特定操作的“一次性通知”。

它内部仅维护一个 flag 状态,一旦设置为完成(done),就只能消费一次,用完需重置。


三、形象比喻:步枪模式的同步机制

我们可以把 rt_completion 比作一把老式步枪:

步骤函数调用类比
上膛(准备完成量)rt_completion_init()向枪膛里装子弹
等待命中目标rt_completion_wait()扣动扳机、瞄准等待打中
任务完成通知rt_completion_done()子弹击中目标,完成通知线程 A

注意:如果你还没瞄准(没有 wait),却提前开枪(done)——这发子弹就白打了,永远不会击中任何目标!


四、使用场景与限制

推荐使用场景:

  • 线程 A 发起任务,等待线程 B 完成操作;
  • 操作顺序是确定的:先 wait,后 done;
  • 一次完成后,不再需要重复触发(或手动重新 init)。

例子:

rt_completion_t comp;
rt_completion_init(&comp);

// 线程 A
send_command();
rt_completion_wait(&comp, RT_WAITING_FOREVER);

// 线程 B
on_command_processed();
rt_completion_done(&comp);

不推荐使用的场景:

场景原因替代建议
done() 早于 wait()可能导致事件永远丢失rt_sem
需要多次触发 / 可重复通知completion 只支持一次完成rt_sem
多线程同时等待同一个事件无法同时唤醒多个线程rt_event
使用后没有手动 deinitinit重复使用将出错或行为不确定手动管理生命周期

五、与其他同步机制对比

同步机制是否可复用是否可积累适合场景
rt_completion❌ 否❌ 否一次性事件完成通知(先 wait 后 done)
rt_sem✅ 是✅ 是可重复的事件触发,线程唤醒
rt_event✅ 是✅ 是多状态事件组合、位图型触发
rt_mutex✅ 是❌ 否资源独占(临界区、串口等)

六、实际工程经验总结

在我们的项目中,有同事曾尝试这样使用 rt_completion

while (1) {
    rt_completion_init(&comp);
    // 等待外设响应
    rt_completion_wait(&comp, RT_WAITING_FOREVER);
    // 处理响应
}

而另一个线程可能在某些情况下先于 wait() 调用了 done(),结果就是:线程永远卡在 wait(),事件信号丢失!

✔️ 正确做法:使用 rt_sem 或者封装更安全的同步结构,确保事件不会提前丢失。


七、工程师建议文案(可用于注释或代码规范):

/* ⚠ 注意:
 * rt_completion 仅用于一次性事件同步。
 * 使用前必须 init,并确保 wait() 在 done() 之前调用。
 * 不适用于可重复、积累事件的同步需求。
 * 如果需求复杂,请使用 rt_sem 或 rt_event 替代。
 */

八、结语

rt_completion 是 RT-Thread 中非常轻巧的同步机制,但它只适合单次、顺序确定、使用简单的任务完成通知场合
在需要更复杂、可重入、可累积的场景中,请优先考虑使用 rt_semrt_event

希望你能把“步枪上弹→等待射击”这个类比记在脑中,用对武器,打中目标!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值