> 文档中心 > Bearpi开发板之HarmonyOS互斥锁

Bearpi开发板之HarmonyOS互斥锁


互斥锁的概念

1、互斥锁又称互斥型信号量,是一种特殊的二值性信号量,用于实现对共享资源的独占式处理。
2、任意时刻互斥锁的状态只有两种:开锁或闭锁。
3、当有任务持有时,互斥锁处于闭锁状态,这个任务获得该互斥锁的所有权。
4、当该任务释放时,该互斥锁被开锁,任务失去该互斥锁的所有权。
5、当一个任务持有互斥锁时,其他任务将不能再对该互斥锁进行开锁或持有。
6、多任务环境下往往存在多个任务竞争同一共享资源的应用场景,互斥锁可被用于对共享资源的保护从而实现独占式访问。
另外,互斥锁可以解决信号量存在的优先级翻转问题。

运作原理

  • 多任务环境下会存在多个任务访问同一公共资源的场景,而有些公共资源是非共享的,需要任务进行独占式处理。互斥锁怎样来避免这种冲突呢?
  • 用互斥锁处理非共享资源的同步访问时,如果有任务访问该资源,则互斥锁为加锁状态。此时其他任务如果想访问这个公共资源则会被阻塞,直到互斥锁被持有该锁的任务释放后,其他任务才能重新访问该公共资源,此时互斥锁再次上锁,如此确保同一时刻只有一个任务正在访问这个公共资源,保证了公共资源操作的完整性。

cmsis_os2的API互斥锁接口简介

  • 创建互斥锁:osMutexId_t osMutexNew (const osMutexAttr_t *attr);
  • 获取互斥锁:osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout);
  • 释放互斥锁:osStatus_t osMutexRelease (osMutexId_t mutex_id);
  • 删除互斥锁:osStatus_t osMutexDelete (osMutexId_t mutex_id);

创建高中低优先级共3个任务和一个互斥对象

#include #include #include "ohos_init.h"#include #include "cmsis_os2.h"#include "wifiiot_gpio.h"#include "wifiiot_gpio_ex.h"void hi_thread(void *p){   osDelay(100);  while(1)  {    osMutexAcquire(p,osWaitForever);     printf("hi thread\n");    osDelay(300);    osMutexRelease(p);  }}void mid_thread(void *p){   (void)p;  osDelay(100);  while(1)  {    printf("mid thread\n");    osDelay(100);  }}void low_thread(void *p){    while(1)  {    osMutexAcquire(p,osWaitForever);    printf("low thread\n");    osDelay(300);    osMutexRelease(p);  }}void my_led_example(void){    GpioInit();    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_2,WIFI_IOT_IO_FUNC_GPIO_2_GPIO);    GpioSetDir(WIFI_IOT_IO_NAME_GPIO_2,WIFI_IOT_GPIO_DIR_OUT); osThreadAttr_t attr;    attr.attr_bits = 0;    attr.cb_mem = NULL;    attr.cb_size = 0;    attr.stack_mem = NULL;    attr.stack_size = 1024;    attr.priority = 25;    static osMutexId_t mutex;    mutex = osMutexNew(NULL);    if (mutex == NULL)    {printf("Falied to create mutex!\n");    }   osThreadId_t id = osThreadNew(hi_thread,mutex,&attr);   if(id == NULL)   { printf("Falied to create hi_thread!\n");   }      attr.priority = 24;    id = osThreadNew(mid_thread,mutex,&attr);   if(id == NULL)   { printf("Falied to create mid_thread!\n");   }    attr.priority = 23;    id = osThreadNew(low_thread,mutex,&attr);   if(id == NULL)   { printf("Falied to create low_thread!\n");   }}SYS_RUN(my_led_example);
  • 编译烧录运行
    在这里插入图片描述

扩展实验代码

#include #include #include "ohos_init.h"#include #include "cmsis_os2.h"#include "wifiiot_gpio.h"#include "wifiiot_gpio_ex.h"void hi_thread(void *p){     osDelay(100U);    osStatus_t status;    while (1)    { // try to acquire mutexstatus = osMutexAcquire(p, osWaitForever); printf("hi_thread is runing.\r\n"); if(status != osOK) {    printf("hi thread acquire mutex failed\r\n"); } else {     printf("hi thread acquire mutex success\r\n"); }  printf("hi thread block 3s\n"); osDelay(300U); printf("hi thread osMutexRelease is called\n"); status = osMutexRelease(p); if(status != osOK) {     printf("hi thread release mutex failed\r\n"); } else {    printf("hi thread release mutex success\r\n"); }    }}void mid_thread(void *p){   (void)p;  osDelay(100);  while(1)  {    printf("mid thread\n");    osDelay(100);  }}void low_thread(void *p){  osStatus_t status;  while (1)  {    status = osMutexAcquire(p, osWaitForever);    printf("low_thread is runing.\r\n");    if(status != osOK)    { printf("lo tread acquire mutex failed\r\n");    }    else    {printf("lo thread acquire mutex success\r\n");    }    // block mutex for 3s    printf("lo thread block 3s\n");    osDelay(300U);    printf("lo thread osMutexRelease is called\n");    status = osMutexRelease(p);    if(status != osOK)    {      printf("lo thread release mutex failed\r\n");    }    else    {      printf("lo thread release mutex success\r\n");    }  }}void my_led_example(void){    GpioInit();    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_2,WIFI_IOT_IO_FUNC_GPIO_2_GPIO);    GpioSetDir(WIFI_IOT_IO_NAME_GPIO_2,WIFI_IOT_GPIO_DIR_OUT); osThreadAttr_t attr;    attr.attr_bits = 0;    attr.cb_mem = NULL;    attr.cb_size = 0;    attr.stack_mem = NULL;    attr.stack_size = 1024;    attr.priority = 25;    static osMutexId_t mutex;    mutex = osMutexNew(NULL);    if (mutex == NULL)    {printf("Falied to create mutex!\n");    }   osThreadId_t id = osThreadNew(hi_thread,mutex,&attr);   if(id == NULL)   { printf("Falied to create hi_thread!\n");   }      attr.priority = 24;    id = osThreadNew(mid_thread,mutex,&attr);   if(id == NULL)   { printf("Falied to create mid_thread!\n");   }    attr.priority = 23;    id = osThreadNew(low_thread,mutex,&attr);   if(id == NULL)   { printf("Falied to create low_thread!\n");   }}SYS_RUN(my_led_example);
  • 编译烧录运行
    Bearpi开发板之HarmonyOS互斥锁

QQ头像吧