Q群:
电话:
邮箱:
地址:
完成量是另外一种任务间同步机制,可用于两个任务之间的同步,即一个任务必须要等待另外一个任务完成某件事情后才能继续执行。可以认为是对信号量其中一种应用场景的简化。
struct os_completion
{
os_uint32_t flag;
os_list_node_t suspended_list;
};
struct os_completion | 说明 |
---|---|
flag | 标志,用来标记完成量状态 |
suspended_list | 阻塞在该完成量上的任务链表 |
接口 | 说明 |
---|---|
os_completion_init | 完成量的初始化 |
os_completion_deinit | 完成量的反初始化 |
os_completion_wait | 等待完成量 |
os_completion_done | 释放完成量 |
该函数用于完成量的初始化,完成量对象由使用者提供,函数原型如下:
void os_completion_init(os_completion_t *completion);
参数 | 说明 |
---|---|
completion | 完成量句柄 |
返回 | 说明 |
无 | 无 |
该函数用于对完成量进行反初始化,函数原型如下:
void os_completion_deinit(os_completion_t *completion);
参数 | 说明 |
---|---|
completion | 完成量句柄 |
返回 | 说明 |
无 | 无 |
该函数用于等待完成量,若完成量暂时无法获得且设置了等待时间,会阻塞当前任务,函数原型如下:
os_err_t os_completion_wait(os_completion_t *completion, os_tick_t timeout);
参数 | 说明 |
---|---|
completion | 完成量句柄 |
timeout | 当完成量暂时无法获取时的等待时间;若为OS_IPC_WAITING_NO,则不等待直接返回OS_ETIMEOUT;若为OS_IPC_WAITING_FOREVER,则会永久等待直到获得完成量;若为其它,则等待设定的timeout时间或者直到获得完成量 |
返回 | 说明 |
OS_EOK | 获取完成量成功 |
OS_ETIMEOUT | 未获取完成量 |
该函数用于释放完成量,会唤醒阻塞在该完成量上的任务,函数原型如下:
void os_completion_done(os_completion_t *completion);
参数 | 说明 |
---|---|
completion | 完成量句柄 |
返回 | 说明 |
无 | 无 |
本例初始化完成量之后,创建了两个任务,一个任务等待完成量,另外一个任务释放完成量
#include <oneos_config.h>
#include <os_dbg.h>
#include <os_errno.h>
#include <os_task.h>
#include <shell.h>
#include <os_ipc.h>
#include <os_completion.h>
#define TEST_TAG "TEST"
#define TASK_STACK_SIZE 1024
#define TASK1_PRIORITY 15
#define TASK2_PRIORITY 16
#define TASK_TIMESLICE 10
static os_completion_t completion_test;
void task1_entry(void *para)
{
os_uint32_t i = 0;
while(1)
{
LOG_W(TEST_TAG, "task1 completion wait");
if (OS_EOK == os_completion_wait(&completion_test, OS_IPC_WAITING_FOREVER))
{
LOG_W(TEST_TAG, "task1 wake up %d", i++);
}
}
}
void task2_entry(void *para)
{
os_uint32_t i = 0;
while (1)
{
LOG_W(TEST_TAG, "task2 completion done %d", i++);
os_completion_done(&completion_test);
os_task_sleep(100);
}
}
void completion_sample(void)
{
os_task_t *task1 = OS_NULL;
os_task_t *task2 = OS_NULL;
os_completion_init(&completion_test);
task1 = os_task_create("task1",
task1_entry,
OS_NULL,
TASK_STACK_SIZE,
TASK1_PRIORITY,
TASK_TIMESLICE);
if (task1)
{
LOG_W(TEST_TAG, "completion_sample startup task1");
os_task_startup(task1);
}
task2 = os_task_create("task2",
task2_entry,
OS_NULL,
TASK_STACK_SIZE,
TASK2_PRIORITY,
TASK_TIMESLICE);
if (task2)
{
LOG_W(TEST_TAG, "completion_sample startup task2");
os_task_startup(task2);
}
}
SH_CMD_EXPORT(test_completion, completion_sample, "test completion");
运行结果如下:
sh />test_completion
W/TEST: completion_sample startup task1
W/TEST: task1 completion wait
W/TEST: completion_sample startup task2
W/TEST: task2 completion done 0
W/TEST: task1 wake up 0
W/TEST: task1 completion wait
W/TEST: task2 completion done 1
W/TEST: task1 wake up 1
W/TEST: task1 completion wait
W/TEST: task2 completion done 2
W/TEST: task1 wake up 2
W/TEST: task1 completion wait
W/TEST: task2 completion done 3
W/TEST: task1 wake up 3
W/TEST: task1 completion wait
W/TEST: task2 completion done 4
W/TEST: task1 wake up 4