HarmonyOS中信号量实验
大家好,我是ST,今天主要和大家聊一聊,如何使用鸿蒙系统中的信号量。
目录
第一:HarmonyOS 内核信号量基本简介
第二:信号量API分析
第三:软件设计
第四:编译调试
第五:运行结果
第一:HarmonyOS 内核信号量基本简介
信号量是基于软件互斥或硬件互斥方法实现的一种用于同步和互斥的机制。信号量是一个确定的二元组(s,q),其中s是一个具有非负初值的整形变量,q是一个初始状态为空的队列。
第二:信号量API分析
osSemaphoreNew()
osSemaphoreId_t osSemaphoreNew(uint32_t max_count,uint32_t initial_count,const osSemaphoreAttr_t *attr)
功能描述:
函数osMessageQueueNew创建并初始化一个消息队列对象。该函数返回消息队列对象标识符,如果出现错误则返回NULL,可以在RTOS启动(调用 osKernelStart)之前安全地调用该函数,也可以在内核初始化 (调用 osKernelInitialize)之前调用该函数。
参数:
名字 | 描述 |
---|---|
max_count | 可用令牌的最大数量. |
initial_count | 可用令牌的初始数量. |
attr | 信号量的属性;空:默认值. |
osSemaphoreRelease()
osStatus_t osSemaphoreRelease(osSemaphoreId_t semaphore_id)
功能描述:函数osSemaphoreRelease释放由参数semaphore_id指定的信号量对象的标记
参数:
名字 | 描述 |
---|---|
semaphore_id | 由osSemaphoreNew获得的信号量ID. |
osSemaphoreAcquire()
osStatus_t osSemaphoreAcquire(osSemaphoreId_t semaphore_id,uint32_t timeout)
功能描述:阻塞函数osSemaphoreAcquire一直等待,直到由参数semaphore_id指定的信号量对象的标记可用为止。如果一个令牌可用,该函数立即返回并递减令牌计数。
参数:
名字 | 描述 |
---|---|
semaphore_id | 由osSemaphoreNew获得的信号量ID. |
timeout | 超时值. |
第三:软件设计
在Semaphore_example函数中,通过osSemaphoreNew()函数创建了sem1信号量,Thread_Semaphore1()函数中通过osSemaphoreRelease()函数释放两个信号量,Thread_Semaphore2()和Thread_Semaphore3()函数中,先开始阻塞等待sem1信号量。只有当Thread_Semaphore1()函数中增加两次信号量,Thread_Semaphore2()和Thread_Semaphore3()才能继续同步运行。若Thread_Semaphore1()函数中只增加一次信号量,那Thread_Semaphore2()和Thread_Semaphore3()只能轮流执行。
void Thread_Semaphore1(void){ while(1){osSemaphoreRelease(sem1); //释放两次sem1信号量,使得Thread_Semaphore2和Thread_Semaphore3能同步执行 osSemaphoreRelease(sem1); //此处若只释放一次信号量,则Thread_Semaphore2和Thread_Semaphore3会交替运行。 printf("Thread_Semaphore1 Release Semap \n"); osDelay(100);}}void Thread_Semaphore2(void){ while(1){osSemaphoreAcquire(sem1,osWaitForever);//申请sem1信号量 printf("Thread_Semaphore2 get Semap \n"); osDelay(1);}}void Thread_Semaphore3(void){ while(1){osSemaphoreAcquire(sem1,osWaitForever);//等待sem1信号量 printf("Thread_Semaphore3 get Semap \n"); osDelay(1);}}void Semaphore_example (void){ osThreadAttr_t attr; attr.attr_bits = 0U; attr.cb_mem = NULL; attr.cb_size = 0U; attr.stack_mem = NULL; attr.stack_size = 1024*4; attr.priority = 24; attr.name = "Thread_Semaphore1"; if (osThreadNew((osThreadFunc_t)Thread_Semaphore1, NULL, &attr) == NULL) { printf("Falied to create Thread_Semaphore1!\n"); } attr.name = "Thread_Semaphore2"; if (osThreadNew((osThreadFunc_t)Thread_Semaphore2, NULL, &attr) == NULL) { printf("Falied to create Thread_Semaphore2!\n"); } attr.name = "Thread_Semaphore3"; if (osThreadNew((osThreadFunc_t)Thread_Semaphore3, NULL, &attr) == NULL) { printf("Falied to create Thread_Semaphore3!\n"); } sem1=osSemaphoreNew(4, 0, NULL); if (sem1 == NULL) { printf("Falied to create Semaphore1!\n"); }}
第四:编译调试
修改BUILD.gn文件
修改applications\BearPi\BearPi-HM_Nano\sample
路径下 BUILD.gn 文件,指定 semp_example
参与编译。
#"A1_kernal_thread:thread_example",#"A2_kernel_timer:timer_example",#"A3_kernel_event:event_example",#"A4_kernel_mutex:mutex_example","A5_kernel_semaphore:semaphore_example",#"A6_kernel_message:message_example",
第五:运行结果
示例代码编译烧录代码后,按下开发板的RESET按键,通过串口助手查看日志,Thread_Semaphore1一次释放两个信号量,Thread_Semaphore2和Thread_Semaphore3同步执行。
Thread_Semaphore1 Release Semap Thread_Semaphore2 get Semap Thread_Semaphore3 get Semap Thread_Semaphore1 Release Semap Thread_Semaphore2 get Semap Thread_Semaphore3 get Semap Thread_Semaphore1 Release Semap Thread_Semaphore2 get Semap Thread_Semaphore3 get Semap