• 基于小熊派Hi3861鸿蒙开发的IoT物联网学习【四】


    一、互斥锁基本概念:
    1、互斥锁又称互斥型信号量,是一种特殊的二值性信号量【二值型信号量可以理解为任务与中断间或者两个任务间的标志,该标志非“满”即“空”】,用于实现对共享资源的独占式处理。
    2、任意时刻互斥锁的状态只有两种:开锁或闭锁
    3、当有任务持有时,互斥锁处于闭锁状态,这个任务获得该互斥锁的所有权。
    4、当该任务释放时,该互斥锁被开锁,任务失去该互斥锁的所有权。
    5、当一个任务持有互斥锁时,其他任务将不能再对该互斥锁进行开锁或持有。
    6、多任务环境下往往存在多个任务竞争同一共享资源的应用场景,互斥锁可被用于对共享资源的保护从而实现独占式访问。另外,互斥锁可以解决信号量存在的优先级翻转问题。
     
    简单的来说:就是同一时刻,同一资源,只能被同一任务共享;
     
    二、LiteOS提供的互斥锁具有如下特点:
    通过优先级继承算法,解决优先级翻转问题。

    三、cmsis_os2的API互斥锁(Mutex)接口简介

    struct osMutexAttr_t //互斥锁的属性结构体


    宏定义:
    #define osMutexRecursive 0x00000001U //递归互斥锁

    #define osMutexPrioInherit 0x00000002U //优先级继承协议

    #define osMutexRobust 0x00000008U //强健的互斥锁

    函数:
    osMutexId_t  osMutexNew (const osMutexAttr_t *attr) //创建并初始化一个互斥锁对象。

    const char * osMutexGetName (osMutexId_t mutex_id) //获取互斥锁对象的名称。

    osStatus_t   osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) //如果它被锁定,则获取互斥锁或超时值。

    osStatus_t   osMutexRelease (osMutexId_t mutex_id) //释放由 osMutexAcquire 获取的互斥锁。

    osThreadId_t  osMutexGetOwner (osMutexId_t mutex_id) //获取拥有互斥锁对象的线程。

    osStatus_t   osMutexDelete (osMutexId_t mutex_id) //删除互斥锁对象。

    互斥锁作用:相互排斥(广为人知的互斥锁)在各种操作系统中用于资源管理。

    单片机器件中的许多资源可以重复使用,但一次只能使用一个线程(例如通信通道,内存和文件)。

    互斥锁用于保护对共享资源的访问。互斥体被创建并在线程之间传递(它们可以获取并释放互斥锁)

    不能从中断服务程序(ISR)调用互斥锁管理函数,这与可以从 ISR 释放的二进制信号不同。有关 RTX5 配置选项,请参阅互斥锁配置。

    同一个线程可以多次使用互斥锁,而不会自行锁定。每当拥有的线程获取互斥锁时,锁定计数就会增加。互斥锁必须多次释放,

    直到锁计数达到零。在达到零时,互斥锁实际上被释放并且可以被其他线程获取。

    案例代码:

    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    
    #include "ohos_init.h"
    #include "cmsis_os2.h"
    
    osMutexId_t mutex_id;
    
    void HighPrioThread(void)
    {
      // wait 1s until start actual work
      osDelay(100U);
      while (1)
      {
        // try to acquire mutex
        osMutexAcquire(mutex_id, osWaitForever);
    
        printf("HighPrioThread is runing.
    ");
        osDelay(300U);
        osMutexRelease(mutex_id);
      }
    }
    
    void MidPrioThread(void)
    {
      // wait 1s until start actual work
      osDelay(100U);
    
      while (1)
      {
        printf("MidPrioThread is runing.
    ");
        osDelay(100);
      }
    }
    
    void LowPrioThread(void)
    {
      while (1)
      {
        osMutexAcquire(mutex_id, osWaitForever);
        printf("LowPrioThread is runing.
    ");
    
        // block mutex for 3s
        osDelay(300U);
        osMutexRelease(mutex_id);
      }
    }
    
    void Mutex_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.name = "HighPrioThread";
      attr.priority = 24;
      if (osThreadNew((osThreadFunc_t)HighPrioThread, NULL, &attr) == NULL)
      {
        printf("Falied to create HighPrioThread!
    ");
      }
    
      
      attr.name = "MidPrioThread";
      attr.priority = 25;
      if (osThreadNew((osThreadFunc_t)MidPrioThread, NULL, &attr) == NULL)
      {
        printf("Falied to create MidPrioThread!
    ");
      }
    
      attr.name = "LowPrioThread";
      attr.priority = 26;
      if (osThreadNew((osThreadFunc_t)LowPrioThread, NULL, &attr) == NULL)
      {
        printf("Falied to create LowPrioThread!
    ");
      }
      mutex_id = osMutexNew(NULL);
      if (mutex_id == NULL)
      {
        printf("Falied to create Mutex!
    ");
      }
    }
    APP_FEATURE_INIT(Mutex_example);


    **主要代码分析**

    在Mutex_example函数中,通过函数创建了互斥锁ID,并创建的三个不同优先级的任务
    在第一秒,高优先级和中优先级线程被延迟。因此,低优先级线程可以启动自己的工作,获得互斥锁并在持有它时延迟。
    在第一秒之后,高优先级和中优先级线程就准备好了。因此高优先级线程获得优先级并尝试获取互斥锁。
    因为互斥锁已经被低优先级线程所拥有,所以高优先级线程被阻塞,中间优先级线程被执行,并开始执行许多非阻塞的工作,
    3S后低优先级释放互斥锁,高优先级线程准备就绪并立即被调度。
     

     

    心有猛虎,细嗅蔷薇
  • 相关阅读:
    C#中 Thread,Task,Async/Await,IAsyncResult 的那些事儿!
    Java8的新特性以及与C#的比较
    点旋转坐标变换
    vc++返回模块路径
    为什么不要 "lock(this)" ? lock object 并是readonly(转载)
    《黄帝内经》要义
    C++多线程编程简单实例
    c++ 获取文件大小
    c# 获取文件夹大小
    自动驾驶仿真工具的下载与安装
  • 原文地址:https://www.cnblogs.com/1314520xh/p/14984149.html
Copyright © 2020-2023  润新知