鸿蒙OpenHarmony【轻量系统内核通信机制(互斥锁)】子系统开发

互斥锁

基本概念

互斥锁又称互斥型信号量,是一种特殊的二值性信号量,用于实现对共享资源的独占式处理。

任意时刻互斥锁的状态只有两种,开锁或闭锁。当任务持有互斥锁时,该互斥锁处于闭锁状态,这个任务获得该互斥锁的所有权。当该任务释放互斥锁时,该互斥锁被开锁,任务失去该互斥锁的所有权。当一个任务持有互斥锁时,其他任务将不能再对该互斥锁进行开锁或持有。

多任务环境下往往存在多个任务竞争同一共享资源的应用场景,互斥锁可被用于对共享资源的保护从而实现独占式访问。另外互斥锁可以解决信号量存在的优先级翻转问题。

运行机制

多任务环境下会存在多个任务访问同一公共资源的场景,而有些公共资源是非共享的,需要任务进行独占式处理。互斥锁怎样来避免这种冲突呢?

用互斥锁处理非共享资源的同步访问时,如果有任务访问该资源,则互斥锁为加锁状态。此时其他任务如果想访问这个公共资源则会被阻塞,直到互斥锁被持有该锁的任务释放后,其他任务才能重新访问该公共资源,此时互斥锁再次上锁,如此确保同一时刻只有一个任务正在访问这个公共资源,保证了公共资源操作的完整性。

图1 轻量系统互斥锁运作示意图 1

接口说明

表1 互斥锁模块接口

功能分类接口描述
互斥锁的创建和删除LOS_MuxCreate:创建互斥锁。 LOS_MuxDelete:删除指定的互斥锁。
互斥锁的申请和释放LOS_MuxPend:申请指定的互斥锁。 LOS_MuxPost:释放指定的互斥锁。

开发流程

互斥锁典型场景的开发流程:

  1. 创建互斥锁LOS_MuxCreate。

  2. 申请互斥锁LOS_MuxPend。 申请模式有三种:无阻塞模式、永久阻塞模式、定时阻塞模式。

    • 无阻塞模式:任务需要申请互斥锁,若该互斥锁当前没有任务持有,或者持有该互斥锁的任务和申请该互斥锁的任务为同一个任务,则申请成功。否则直接返回并继续运行当前任务,不会产生阻塞。
    • 永久阻塞模式:任务需要申请互斥锁,若该互斥锁当前没有被占用,则申请成功。否则,该任务进入阻塞态,系统切换到就绪任务中优先级高者继续执行。任务进入阻塞态后,直到有其他任务释放该互斥锁,阻塞任务才会重新得以执行。
    • 定时阻塞模式:任务需要申请互斥锁,若该互斥锁当前没有被占用,则申请成功。否则该任务进入阻塞态,系统切换到就绪任务中优先级高者继续执行。任务进入阻塞态后,指定时间超时前有其他任务释放该互斥锁,或者用户指定时间超时后,阻塞任务才会重新得以执行。
  3. 释放互斥锁LOS_MuxPost。

    • 如果有任务阻塞于指定互斥锁,则唤醒被阻塞任务中优先级高的,该任务进入就绪态,并进行任务调度;
    • 如果没有任务阻塞于指定互斥锁,则互斥锁释放成功。
  4. 删除互斥锁LOS_MuxDelete。

说明:

  • 互斥锁支持嵌套,即申请该互斥锁的任务与已经持有该互斥锁的任务为同一个任务时会认为申请成功,按申请次数对应的去释放该锁即可。
  • 互斥锁不能在中断服务程序中使用。
  • LiteOS-M内核作为实时操作系统需要保证任务调度的实时性,尽量避免任务的长时间阻塞,因此在获得互斥锁之后,应该尽快释放互斥锁。
  • 持有互斥锁的过程中,不得再调用LOS_TaskPriSet等接口更改持有互斥锁任务的优先级。

编程实例

实例描述

本实例实现如下流程。

  1. 任务ExampleMutex创建一个互斥锁,锁任务调度,创建两个任务ExampleMutexTask1、ExampleMutexTask2。ExampleMutexTask2优先级高于ExampleMutexTask1,解锁任务调度。
  2. ExampleMutexTask2被调度,以永久阻塞模式申请互斥锁,并成功获取到该互斥锁,然后任务休眠100Tick,ExampleMutexTask2挂起,ExampleMutexTask1被唤醒。
  3. ExampleMutexTask1以定时阻塞模式申请互斥锁,等待时间为10Tick,因互斥锁仍被ExampleMutexTask2持有,ExampleMutexTask1挂起。10Tick超时时间到达后,ExampleMutexTask1被唤醒,以永久阻塞模式申请互斥锁,因互斥锁仍被ExampleMutexTask2持有,ExampleMutexTask1挂起。
  4. 100Tick休眠时间到达后,ExampleMutexTask2被唤醒, 释放互斥锁,唤醒ExampleMutexTask1。ExampleMutexTask1成功获取到互斥锁后,释放并删除互斥锁。

示例代码

示例代码如下:

本演示代码在 ./kernel/liteos_m/testsuites/src/osTest.c 中编译验证,在TestTaskEntry中调用验证入口函数ExampleMutex。

#include "los_mux.h"/* 互斥锁句柄 */
UINT32 g_testMux;VOID ExampleMutexTask1(VOID)
{UINT32 ret;printf("task1 try to get  mutex, wait 10 ticks.\n");/* 申请互斥锁 */ret = LOS_MuxPend(g_testMux, 10);if (ret == LOS_OK) {printf("task1 get mutex g_testMux.\n");/* 释放互斥锁,这个分支正常不应该进来 */LOS_MuxPost(g_testMux);LOS_MuxDelete(g_testMux);return;}if (ret == LOS_ERRNO_MUX_TIMEOUT ) {printf("task1 timeout and try to get mutex, wait forever.\n");/* 申请互斥锁 */ret = LOS_MuxPend(g_testMux, LOS_WAIT_FOREVER);if (ret == LOS_OK) {printf("task1 wait forever, get mutex g_testMux.\n");/* 释放互斥锁 */LOS_MuxPost(g_testMux);/* 删除互斥锁 */LOS_MuxDelete(g_testMux);printf("task1 post and delete mutex g_testMux.\n");return;}}return;
}VOID ExampleMutexTask2(VOID)
{printf("task2 try to get  mutex, wait forever.\n");/* 申请互斥锁 */(VOID)LOS_MuxPend(g_testMux, LOS_WAIT_FOREVER);printf("task2 get mutex g_testMux and suspend 100 ticks.\n");/* 任务休眠100Ticks */LOS_TaskDelay(100);printf("task2 resumed and post the g_testMux\n");/* 释放互斥锁 */LOS_MuxPost(g_testMux);return;
}UINT32 ExampleMutex(VOID)
{UINT32 ret;TSK_INIT_PARAM_S task1 = { 0 };TSK_INIT_PARAM_S task2 = { 0 };UINT32 taskId01;UINT32 taskId02;/* 创建互斥锁 */LOS_MuxCreate(&g_testMux);/* 锁任务调度 */LOS_TaskLock();/* 创建任务1 */task1.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleMutexTask1;task1.pcName       = "MutexTsk1";task1.uwStackSize  = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;task1.usTaskPrio   = 5;ret = LOS_TaskCreate(&taskId01, &task1);if (ret != LOS_OK) {printf("task1 create failed.\n");return LOS_NOK;}/* 创建任务2 */task2.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleMutexTask2;task2.pcName       = "MutexTsk2";task2.uwStackSize  = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;task2.usTaskPrio   = 4;ret = LOS_TaskCreate(&taskId02, &task2);if (ret != LOS_OK) {printf("task2 create failed.\n");return LOS_NOK;}/* 解锁任务调度 */LOS_TaskUnlock();return LOS_OK;
}

结果验证

编译运行得到的结果为:

task2 try to get  mutex, wait forever.
task2 get mutex g_testMux and suspend 100 ticks.
task1 try to get  mutex, wait 10 ticks.
task1 timeout and try to get mutex, wait forever.
task2 resumed and post the g_testMux
task1 wait forever, get mutex g_testMux.
task1 post and delete mutex g_testMux.

以上就是本篇文章所带来的鸿蒙开发中一小部分技术讲解;想要学习完整的鸿蒙全栈技术。可以在结尾找我可全部拿到!
下面是鸿蒙的完整学习路线,展示如下:
1

除此之外,根据这个学习鸿蒙全栈学习路线,也附带一整套完整的学习【文档+视频】,内容包含如下

内容包含了:(ArkTS、ArkUI、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、鸿蒙南向开发、鸿蒙项目实战)等技术知识点。帮助大家在学习鸿蒙路上快速成长!

鸿蒙【北向应用开发+南向系统层开发】文档

鸿蒙【基础+实战项目】视频

鸿蒙面经

2

为了避免大家在学习过程中产生更多的时间成本,对比我把以上内容全部放在了↓↓↓想要的可以自拿喔!谢谢大家观看!
3

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/144890.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

了解CRM销售自动化:类型、优势、策略和工具

对于疲于手动追踪潜在客户和管理客户关系的销售人员而言,销售自动化提供了一种有效的解决方案,它能够简化这些繁琐的任务,从而使销售团队能够专注于其核心优势——销售本身。 销售自动化是什么? 销售自动化是指运用软件工具自动…

高德地图JS API AMap.MouseTool绘制

fang 🤖 作者简介:水煮白菜王 ,一位资深前端劝退师 👻 👀 文章专栏: 高德AMap专栏 ,记录一下平时在博客写作中,总结出的一些开发技巧✍。 感谢支持💕💕&#…

TPDO触发条件如何满足?

在上一期中,我们了解到TPDO(传输过程数据对象)的传输类型有很多种:同步周期性传输、RTR(远程传输请求)以及异步制造商特定事件等。这些类型的触发条件主要分为三种:同步(SYNC&#x…

Java 多态(难)

1. 即同一方法可以根据发送对象的不同而采用多种不同的行为方式。 2.一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多。 举例说明:新建两个类,Person类和Student类,Student类继承Person类&#xff1a…

Xinstall助力App推广,下载自动绑定提升转化率

在App推广和运营的过程中,我们经常会遇到一些痛点。比如,用户下载App后需要手动进行一系列繁琐的操作才能完成注册和绑定,这不仅影响了用户体验,还降低了转化率。那么,有没有一种方法能够简化这个过程,提升…

VsCode汉化教程(新手教程)

刚用VsCode的可能不知道怎么汉化,这里出个给新手的教程。 一.下载汉化插件 1.点击左侧边栏中的扩展 2.下载简体中文汉化插件(搜索chinese就行) 二.切换语言 很多人认为下完成就汉化成功了,实际上需要自己切换,这个插…

苹果撤诉NSO,竟因惧怕情报泄露?!VMware vCenter惊现高危漏洞!20万台设备遭感染!新型物联网僵尸网络肆虐全球! | 安全周报0920

新闻1:苹果撤诉NSO,竟因惧怕情报泄露?! 苹果公司已提交动议,“自愿”撤销对商业间谍软件供应商NSO集团的诉讼,理由是风险形势的转变可能导致关键“威胁情报”信息的暴露。 这一进展最初由《华盛顿邮报》于…

C++模拟实现list:list、list类的初始化和尾插、list的迭代器的基本实现、list的完整实现、测试、整个list类等的介绍

文章目录 前言一、list二、list类的初始化和尾插三、list的迭代器的基本实现四、list的完整实现五、测试六、整个list类总结 前言 C模拟实现list:list、list类的初始化和尾插、list的迭代器的基本实现、list的完整实现、测试、整个list类等的介绍 一、list list本…

电脑怎么录屏?超实用免费电脑录屏软件推荐与教程

在数字化时代,电脑录屏已成为我们工作、学习和娱乐中不可或缺的一部分。无论是录制教学视频、游戏直播、会议记录还是软件操作演示,一款好用的录屏软件都能大大提升我们的效率。今天,我们就来介绍五款超实用的电脑录屏软件,并附上…

【prefect】python任务调度工具 Prefect | 可视化任务工具 | Python自动化的终极武器 | 高效数据管道管理

一、产品介绍 1、官方 Github https://github.com/PrefectHQ/prefect 2、官方文档 https://docs.prefect.io/3.0/get-started/index 3、Pgsql说明 正确的python链接pgsql如下: import psycopg2 from sqlalchemy import create_enginedef connect_with_psycopg2(…

Node.js官网无法正常访问时安装NodeJS的方法

目录 一、使用 nvm 进行安装二、通过阿里云开源镜像站进行安装 一、使用 nvm 进行安装 此时如果直接使用 nvm install 命令进行安装会报错: nvm install 16.14.0Could not retrieve https://nodejs.org/dist/latest/SHASUMS256.txt. Get “https://nodejs.org/dis…

对称加密算法使用示例

Demo包括以下对称加密算法组合 备注:XTS仅支持AES128和AES256,不支持AES192 from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.primitives import cmac from cryptography.hazmat.primitives.…

MFC-基础架构

前言 各位师傅大家好,我是qmx_07,今天讲解MFC的基础架构 概述 介绍:MFC(Microsoft Foundation Classes)是微软公司提供的一个类库,用于在 Windows 操作系统下进行 C 应用程序开发MFC把Windows SDK API函…

解决:The play() request was interrupted by a call to pause().报错

前言: 最近在公司中实现进入页面之后点击单词直接播放音频的时候,发现音频并不会播放声音,并且控制台报错: 研究之后找到了解决方案,与小伙伴们进行分享 原因: 首先看这句话的意思: 在调用 …

红黑树构建模拟实现

目录 一.红黑树概述 二.红黑树的性质 ​编辑 三.构建红黑树模拟实现 插入新节点情况分析 情况一、cur为红色,parent为红色,grandfather为黑色,uncle存在且为红 情况二、cur为红色,parent为红色,grandfather为黑色…

VS运行程序时报错--无法定位程序输入点

发现问题: VS 在运行程序时,报错: 找到原因: 因为我在替换动态库的时候,只替换了lib库,没有替换运行目录下的dll库,运行时候的dll与程序中的lib库不对应。 替换库后就能解决这个问题。

PyTorch使用------自动微分模块

目录 🍔 梯度基本计算 1.1 单标量梯度的计算 1.2 单向量梯度的计算 1.3 多标量梯度计算 1.4 多向量梯度计算 1.5 运行结果💯 🍔 控制梯度计算 2.1 控制不计算梯度 2.2 注意: 累计梯度 2.3 梯度下降优化最优解 2.4 运行结果&#x1…

dgl库安装

此篇文章继续上一篇pytorch已经安装成功的情况 (python3.9,pytorch2.2.2,cuda11.8) 上一篇pytorch安装教学链接 选择与之匹配的版本 输入下方代码进行测试 import dgl.data dataset dgl.data.CoraGraphDataset() print(‘Numb…

契约锁与您相约2024新疆数字经济创新大会暨新疆数字丝路博览会

9月20日,由新疆数字经济联合会主办,多家行业协会及企业共同承办的“2024(第一届)新疆数字经济创新发展大会暨新疆数字丝路博览会”在新疆国际会展中心盛大开幕,活动期间,契约锁作为电子签章行业领先的服务商携数字可信系列产品亮相…

小程序服务零工市场

零工市场小程序有着信息发布、岗位匹配、线上接单、零工人员保障险参保、技能培训、费用结算、完工确认、服务评价、纠纷调解等功能,为求职者和雇主搭建一座高效、便捷、精准的对接桥梁。 用工单位通过小程序的“雇主找人”,发布招聘信息,找到…