一、互斥锁基本概念:
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.\r\n");
osDelay(300U);
osMutexRelease(mutex_id);
}
} void MidPrioThread(void)
{
// wait 1s until start actual work
osDelay(100U); while (1)
{
printf("MidPrioThread is runing.\r\n");
osDelay(100);
}
} void LowPrioThread(void)
{
while (1)
{
osMutexAcquire(mutex_id, osWaitForever);
printf("LowPrioThread is runing.\r\n"); // 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!\n");
} attr.name = "MidPrioThread";
attr.priority = 25;
if (osThreadNew((osThreadFunc_t)MidPrioThread, NULL, &attr) == NULL)
{
printf("Falied to create MidPrioThread!\n");
} attr.name = "LowPrioThread";
attr.priority = 26;
if (osThreadNew((osThreadFunc_t)LowPrioThread, NULL, &attr) == NULL)
{
printf("Falied to create LowPrioThread!\n");
}
mutex_id = osMutexNew(NULL);
if (mutex_id == NULL)
{
printf("Falied to create Mutex!\n");
}
}
APP_FEATURE_INIT(Mutex_example);

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

基于小熊派Hi3861鸿蒙开发的IoT物联网学习【四】的更多相关文章

  1. 基于小熊派Hi3861鸿蒙开发的IoT物联网学习【一】

    基于小熊派鸿蒙季BearPi-HM_Nano HarmonyOS 鸿蒙系统Hi3861开发板NFC  开发步骤:1.购买开发板:某宝上购买就行 2.安装开发环境 3.下载源码 4.编写案例并执行 开发 ...

  2. 基于小熊派Hi3861鸿蒙开发的IoT物联网学习【五】

    BearPi-HM_Nano开发板鸿蒙OS内核编程开发--消息队列 什么是消息队列?        答:消息队列中间件是分布式系统中重要的组件,主要解决应用耦合.异步消息.流量削锋等问题.实现高性能. ...

  3. 基于小熊派Hi3861鸿蒙开发的IoT物联网学习【三】

    软件定时器:是基于系统Tick时钟中断且由软件来模拟的定时器,当经过设定的Tick时钟计数值后会触发用户定义的回调函数.定时精度与系统Tick时钟的周期有关. 定时器运行机制: cmsis_os2的A ...

  4. 基于小熊派Hi3861鸿蒙开发的IoT物联网学习【二】

    HarmonyOS内核开发-信号量开发案例学习记录   一.LiteOS里面的任务管理介绍: 任务状态通常分为以下四种: 就绪(Ready):该任务在就绪列表中,只等待CPU. 运行(Running) ...

  5. 基于小程序云Serverless开发微信小程序

    本文主要以使用小程序云Serverless服务开发一个记事本微信小程序为例介绍如何使用小程序云Serverless开发微信小程序.记事本小程序的开发涉及到云函数调用.云数据库存储.图片存储等功能,较好 ...

  6. 如何基于App SDK快速地开发一个IoT App?

    一.背景及大纲介绍 在如今物联网DCM(Device.Connect.Manage)的大框架下,有一个应用层来分析和处理数据,是必备技能.但是,对于一个公司来说,因为研发能力或者研发时间的原因,可能很 ...

  7. 华为云MVP熊保松谈物联网开发:华为云IoT是首选,小熊派是神器

    摘要:在AI.5G的技术驱动下,物联网行业的发展愈加如火如荼,开发者在技术的快速更迭间,也得乘风破浪跟上新技术的节奏. 在AI.5G的技术驱动下,物联网行业的发展愈加如火如荼,开发者在技术的快速更迭间 ...

  8. 开发实践丨用小熊派STM32开发板模拟自动售货机

    摘要:本文内容是讲述用小熊派开发板模拟自动售货机,基于论坛提供的工程代码,通过云端开发和设备终端开发,实现终端数据在的华为云平台显示. 本文内容是讲述用小熊派开发板模拟自动售货机,基于论坛提供的工程代 ...

  9. 【资源下载】Linux下的Hi3861一站式鸿蒙开发烧录(附工具)

    下载附件 2021春节前夕,华为发布了 HUAWEI DevEco Device Tool 2.0 Beta1,整体提供了异常强大的功能.得知消息后,我在第一时间带着无比兴奋的心情下载尝鲜,但结果却是 ...

随机推荐

  1. 04:全局解释器锁(GIL)

    1 全局解释器锁(GIL) 0 pypy(没有全局解释器锁) cpython(99.999999%)    -pypy python好多模块用不了,1 全局解释器锁,GIL锁(cpython解释器的问 ...

  2. 第11章 PADS功能使用技巧(1)-最全面

    一.如何走蛇形线? 蛇形线是布线过程中常用的一种走线方式,其主要目的是为了调节延时满足系统时序设计要求,但是设计者应该有这样的认识:蛇形线会破坏信号质量,改变传输延时,布线时要尽量避免使用,因此一块P ...

  3. vue环境搭建以及使用vue-cli创建项目

    我要跑vue项目,所以我要搞vue. 1.环境搭建 进入node官网下载对应版本的node,一步步安装即可. 安装会自动配置路径和npm包管理环境,通过node -v进行验证 2.安装vue-cli脚 ...

  4. 第三天编程学习Hello,World!

    真正意义上迈入编程的大门--Hello,World! 新建一个文件夹(最好在桌面),方便存放代码 新建一个文件(如:Hello.txt) 改文件后缀名为.java 扩展文件得到Hello.java 编 ...

  5. Redis之Sentinel

    Redis的主从复制模式下,一旦主节点由于故障不能提供服务,需要人工将从节点晋升为主节点,同时还要通知应用方更新主节点地址,对于很多应用场景这种故障处理的方式是无法接受的.可喜的是Redis从 2.8 ...

  6. 1、mysql基础入门(1)

    1.mysql基础入门: 1.1.数据库介绍:

  7. 『心善渊』Selenium3.0基础 — 17、Selenium操作浏览器窗口的滚动条

    目录 1.为什么操作滚动条 2.Selenium如何操作滚动条 3.Selenium操作滚动条方法 4.操作滚动条示例 5.下拉至聚焦元素的位置 (1)实现步骤: (2)实现示例: 1.为什么操作滚动 ...

  8. 通过RenderDoc真机抓取数据来落地验证和解决特效性能的问题

    前言 需求是来自于我在为我司的一个线上RPG游戏做特效的性能优化的过程中,需要验证对特效的一个改动是否能够提高性能,当然这个改动是在不影响美术效果的前提. 特效性能问题 技能特效 主角的一个大招(技能 ...

  9. SDLC开发安全流程

    2020年12月9日跟内部小伙伴分享SDLC流程及安全的一些思考,简单画了一个图,时间过得太快,记录一下 参考 https://blog.csdn.net/liqiuman180688/article ...

  10. Windows10:虚拟机开机导致win10黑屏、蓝屏

    管理员身份打开cmd(命令提示符) 执行如下5个命令 netsh winsock reset net stop VMAuthdService net start VMAuthdService net ...