completion是什么?completion怎么使用呢?

1.completion 是什么
completion 直接翻译过来是完成,所以我更愿意称 rt_completion 为 完成量。在 rt-thread 的文档中心 中讲线程间通讯(ipc)时,只介绍了,信号量, 互斥量, 事件集,其实 rt_completion 可以认为是轻量级的二值信号量。
2.completion 怎么使用
completion 的使用非常简单
定义一个完成量
struct rt_completion completion;
初始化完成量
rt_completion_init(&completion);
等待完成量
rt_completion_wait(&completion);
释放完成量
rt_completion_done(&completion);
3.completion 的实现
completion 的 api 非常少,可以通过简单的代码去分析
初始化完成量
void rt_completion_init(struct rt_completion *completion)
{
rt_base_t level;
rt_assert(completion != rt_null);
level = rt_hw_interrupt_disable();
completion->flag = rt_uncompleted;
rt_list_init(&completion->suspended_list);
rt_hw_interrupt_enable(level);
}
干了两件事:
设置 flag 为 rt_uncompleted
初始化完成量的链表
等待完成量(以下代码有删减)
rt_err_t rt_completion_wait(struct rt_completion *completion,
rt_int32_t timeout)
{
result = rt_eok;
thread = rt_thread_self();
level = rt_hw_interrupt_disable();
if (completion->flag != rt_completed)
{
if (timeout == 0)
{
}
else
{
/* reset thread error number */
thread->error = rt_eok;
/* suspend thread */
rt_thread_suspend(thread);
/* add to suspended list */
rt_list_insert_before(&(completion->suspended_list),
&(thread->tlist));
/* current context checking */
rt_debug_not_in_interrupt;
/* start timer */
if (timeout > 0)
{
/* reset the timeout of thread timer and start it */
rt_timer_control(&(thread->thread_timer),
rt_timer_ctrl_set_time,
&timeout);
rt_timer_start(&(thread->thread_timer));
}
/* enable interrupt */
rt_hw_interrupt_enable(level);
/* do schedule */
rt_schedule();
/* thread is waked up */
result = thread->error;
level = rt_hw_interrupt_disable();
}
}
/* clean completed flag */
completion->flag = rt_uncompleted;
return result;
}
主要做了以下工作:
关中断:rt_hw_interrupt_disable();
挂起当前线程:rt_thread_suspend(thread);
把挂起状态插入到线程的链表中:rt_list_insert_before
确保当前函数执行不是在中断中:rt_debug_not_in_interrupt;
设置并启动定时器:rt_timer_start(&(thread->thread_timer));
开中断:rt_hw_interrupt_enable(level);
开调度器:rt_schedule();
获取当前线程状态:result = thread->error;
设置完成量的标志位:completion->flag = rt_uncompleted;
返回线程状态
这样就完成了线程的挂起。
完成完成量(以下代码有删减)
void rt_completion_done(struct rt_completion *completion)
{
level = rt_hw_interrupt_disable();
completion->flag = rt_completed;
if (!rt_list_isempty(&(completion->suspended_list)))
{
/* there is one thread in suspended list */
struct rt_thread *thread;
/* get thread entry */
thread = rt_list_entry(completion->suspended_list.next,
struct rt_thread,
tlist);
/* resume it */
rt_thread_resume(thread);
rt_hw_interrupt_enable(level);
/* perform a schedule */
rt_schedule();
}
}
主要做了以下工作:
关中断:rt_hw_interrupt_disable();
设置 flag 为 rt_completed
检查链表不为空:rt_list_isempty
获取到当前等待完成量的句柄:rt_list_entry
启动被挂起的线程:rt_thread_resume(thread);
开中断:rt_hw_interrupt_enable(level);
开调度:rt_schedule();
4.completion 与信号量的对比
completion api 个数少,资源占用少,只能释放获取,不支持多次释放
semaphore api 个数多,资源占用较多,使用灵活,可以尝试获取,可以多次释放,
5.completion 如何加入工程
标准版 rt-thread 中的 completion 源码在 \\rt-thread\\components\\drivers\\src\\completion.c在你要使用的文件中#include completion.h直接就可以使用。
nano 版 rt-thread 直接拷贝completion.c 和 completion.h 添加到工程就可以使用。

Cat-M1和NB-IoT的异同及应用综述
华为两款全新智能手表曝光:或与P30一同发布!
魅族十分突然的宣布了新的手机,这手机到底是什么样呢?
RTX 4070有了什么样的变数,是更高了还是更低了?
Micro LED市场营收额将在2027年超过700亿美元
completion是什么?completion怎么使用呢?
关于LTO电池和充电/电压监控,你想了解的知识点都在这里!
元件分销转型升级样本 世强元件电商获2017中国智造金长城奖
关于FPGA将带来至多25倍单位功耗性能提升的分析和介绍
十大运动蓝牙耳机品牌排行榜、2022十大运动耳机最新排行榜!
我国科技企业缺“芯”少魂 芯片进口花费是原油的两倍
基于DSP开发板与光源和仿真器的防疲劳驾驶监测系统的设计
“无人化”时代来临,你的前台该更新啦!
高可靠性的可编程电源管理解决方案
魅蓝一脸尴尬!荣耀再次发布“魅蓝海”
纸机烘缸锥度轴磨损原因及修复方法
你可以区分无人机和航模吗
传闻已久的苹果电动汽车原型车已经在加州上路测试
物联网即服务新用例有哪些?2021年高通智慧城市加速大会上有答案
【破碎机修复】从故障原因到施工步骤,全方位讲解破碎机轴磨损的在线修复工艺