嵌入式实时操作系统的设计与开发(互斥量学习)

一个无论多么小的系统,都会有大系统的缩影,就像俗话说“麻雀虽小五脏俱全”。

嵌入式实时操作系统中除了基本调度机制(创建线程、调度线程、挂起线程等),事件处理机制(中断管理、时钟管理)、内存管理机制外,也有一般操作所具有的线程交互机制,如 互斥机制、同步机制、通信机制等。

并发线程可共享系统中的各类资源,如全局变量、表格、队列、打印机等,这些资源被称为临界资源,当诸线程在访问这些临界资源时,必须互斥访问。

互斥,顾名思义,大家都要相互排斥,因此在同一个时刻,只能有一个任务拥有互斥量。

大家把每个线程中访问临界资源的那段代码称为临界区,把线程刚开始执行临界区代码和退出临界区代码的那一刻称为临界点。

临界区的代码需要互斥访问,即不允许多个线程,中断同时执行临界区域代码

HAL_INTR ENABLE:CPSIE imov pc,lrHAL_INTR_DISABLE:CPSID imov pc,lr

线程和中断处理程序互斥:当线程在临界点关了中断,线程在执行临界区代码时,中断肯定不会发生,所以不会出现中断和线程同时访问临界区代码的情况。

互斥机制

除了HAL_ENTER_CRITICAL、HAL_EXIT_CRITICAL临界点机制可实现互斥外,还可以用互斥量机制实现互斥。

临界点机制是整个临界区域都关中断,而互斥量只是申请互斥量和释放互斥量时关中断,同时互斥量机制可能会引起线程挂起,导致线程切换

使用互斥量机制时临界区代码往往都比较长,对于线程之间互斥的代码区域,如果这段区域很小,小到执行时间少于线程切换的时间,优先使用临界点。

互斥量

使用互斥量(Mutex)可以有效管理系统中的独占资源,进而利用这一特性来实现对临界资源的管理,以便一个核上的多个任务,多个核上的多个任务在访问临界资源不会互相干扰,产生异常结果。
aCoral互斥量的实现依赖于事件控制块。

typedef enum{ACORAL_EVENT_SEM, //信号量ACORAL_EVENT_MUTEX //互斥量
}acoralEventEnum;typedef struct{acoral_res_t res; //event也是一种资源unsigned char type;int count;//共用型变量,当type值不同时,count代表的意思也不同,当为互斥量时,16~24位代表这个互斥量的优先级天花板,这个值在互斥量被创建的时候就确定了并且不会改变,低16位中的高8位表示这个互斥量被占用时,因为尝试申请互斥量而被阻塞的线程中最高的优先级,低8位在互斥量没有被上锁时,为全1,表示互斥量可用;在被上锁,也就是被占用时,会赋值为占用它的线程的原始优先级。之所以说是原始优先级,是因为占用线程在使用互斥量的过程中可能被提升优先级,那么在释放互斥量之后就要恢复之前的优先级,从count的低八位取指。acoral_list_t wait_queue; //等待使用这个event的线程队列char *name; //名字void *data; //当event是mutex或semaphore时,指向占用线程,当event是消息队列时,存放传递的消息
}acoral_evt_t;

创建互斥量
创建互斥量的时候,需要指定的第一个参数为:互斥量的优先级,这个优先级为使用该互斥量的所有线程中最高的优先级,指定该参数是为了避免优先级反转,支持优先级继承;而第二个参数是该接口的返回信息,用来通知信号量创建者在创建过程的状态。
当创建成功时,返回指向该互斥量的指针

acoral_evt_t *acoral_mutex_create(unsigned char prio, unsigned int *err)
{acoral_evt_t *evt;evt = acoral_alloc_evt();//从资源内存池中分配一个事件块,分配的方式和线程控制块类似if(NULL == evt){*err = MUTEX_ERR_NULL;return NULL;}evt->count = (prio << 16) | MUTEX_AVAI | MUTEX_U_MASK;evt->type = ACORAL_EVENT_MUTEX;evt->data = NULL;acoral_evt_init(evt);//初始化互斥量,创建互斥量的最后一步是对其进行初始化,return evt;
}
acoral_evt_t *acoral_alloc_evt()
{return (acoral_evt_t *)acoral_get_res(&acoral_evt_pool_ctrl);
}
void acoral_evt_init(acoral_evt_t *evt)
{acoral_init_list(&evt->wait_queue);
}

优先级反转

在这里插入图片描述
T1的优先级大于T2大于T3,T1与T3会访问共享资源S,T2不会。

  1. T3在时刻0到达,并立即得以运行,随后,在t0时刻开始进入临界区访问共享资源S。
  2. 在时刻t1,T1到达系统,T1抢占T3获得运行权,t2时刻,T1欲访问共享资源S,而此时S被T3占用,T1被切换到等待队列,CPU的执行权重新交给T3,T3继续访问S。
  3. 在时刻t3,T2到达系统,T2抢占T3获得运行权,直到时刻t4,T2执行结束,CPU执行权交给T3。
  4. 时刻t5,T3结束共享资源的访问,释放共享资源S,这样,T1获得CPU使用权,直到t6。

虽然T2优先级小于T1,但T2延迟了T1的运行,T2先于T1执行完,该现象在RTOS中被称为优先级反转。

在多个任务需要访问共享资源的情况下可能会出现高优先级任务被低优先级任务阻塞,并等待低优先级任务运行,在此过程中,高优先级任务需要等待低优先级任务释放共享资源,而低优先级任务又在等待不访问共享资源的中等优先级任务的现象,称为优先级反转。

优先级反转造成了调度的不确定性。

优先级继承指当一个任务阻塞了一个或多个高优先级任务时,该任务将不使用原来的优先级,而暂时使用被阻塞任务中的最高优先级作为执行临界区的优先级,当该任务退出临界区时,再恢复到其最初优先级。

基本步骤如下:

  1. 如果任务T为具有最高优先级的就绪任务,则T将获得运行权。在任务T进入临界区前,首先需要通过RTOS提供的API请求获得该临界区的互斥量S(acoral_mutex_pend())
  2. 如果互斥量S已经被上锁,则任务T的请求被拒绝。在该情况下,任务T被拥有互斥量S的任务所阻塞。
  3. 如果互斥量S未被上锁,则任务获得互斥量S而进入临界区。当任务T退出临界区时,使用临界区过程中所上锁的信号被解锁(acoral_mutex_post()),此时如果有其它任务因为请求临界区而被阻塞,则其中具有最高优先级的任务将被激活,处于就绪状态。
  4. 任务T将保持被分配的原有优先级不变,除非任务T进入了临界区并阻塞了更高优先级的任务。则T将继承被任务T阻塞的所有任务的最高优先级,直到任务T退出临界区。当T退出临界区时,将恢复到进入临界区前的原有优先级。
  5. 优先级继承具有传递性。

是否存在优先级反转的条件:

  1. 已占有互斥量的线程优先级不是创建互斥量时设置的最高优先级。
  2. 且已占有互斥量的线程优先级小于当前线程的优先级。
  3. 且已占有互斥量的线程和当前线程并发使用一个CPU时。
acoralMutexRetVal acoral_mutex_post(acoral_evt_t *evt)
{unsigned char ownerPrio;unsigned char highPrio;acoral_thread_t *thread;acoral_thread_t *cur;acoral_enter_critical();if (NULL == evt){acoral_print("mutex NULL\n");acoral_exit_critical();return MUTEX_ERR_NULL; /*error*/}highPrio = (unsigned char)(evt->count >> 8);ownerPrio = (unsigned char)(evt->count & MUTEX_L_MASK);cur = acoral_cur_thread;if(highPrio != 0 && cur->prio != highPrio && cur->prio != ownerPrio){acoral_print("mutex prio err\n");acoral_exit_critical();return MUTEX_ERR_UNDEF;}cur->evt = NULL;if(cur->prio != ownerPrio){acoral_change_prio_self(ownerPrio);}thread = acoral_evt_high_thread(evt);if(thread == NULL){evt->count |= MUTEX_AVAI;evt->data = NULL;acoral_exit_critical();return MUTEX_SUCCED;}timeout_queue_del(thread);acoral_evt_queue_del(thread);evt->count &= MUTEX_U_MASK;evt->count |= thread->prio;evt->data = thread;acoral_rdy_thread(thread);acoral_exit_critical();acoral_sched();return MUTEX_SUCCED;
}

删除互斥量:当互斥量不再使用时,需要对其进行删除,以回收内存空间,删除互斥量的接口acoralMutexRetVal acoral_mutex_del(acoral_evt_t *evt, unsigned int opt)
需要传递对应的指向互斥量结构的指针,同时需要指定删除时的属性,当opt的值为ACORAL_MUTEX_FORCEDEL时,不管有无线程在等待,都会删除互斥量,归还互斥量块到事件块缓冲池中。
当opt的值为ACORAL_NORMALDEL时,如果有线程在等待,则不会进行删除,通过返回值通知删除状态。

acoralMutexRetVal acoral_mutex_del(acoral_evt_t *evt, unsigned int opt)
{if(NULL == evt){return MUTEX_ERR_NULL;}if(ACORAL_EVENT_MUTEX != evt->type){return MUTEX_ERR_TYPE;}acoral_enter_critical();if(acoral_evt_queue_empty(evt)){acoral_exit_critical();return MUTEX_SUCCED;}else{/*有等待任务*/acoral_exit_critical();return MUTEX_ERR_TASK_EXIST;}
}

对于多核嵌入式平台,aCoral提供了另一种互斥机制:自旋锁。
原来的临界点机制仅仅通过关中断,是没法实现多核环境下互斥访问的,因为临界点机制只能保证同一个核上的线程之间线程和中断的互斥。
而在多核情况下,线程是可同时在不同核上运行的,这就需要一种核间互斥的机制,也就是自旋锁。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【c++】运算符重载实例

重载自增自减运算符 Intger num(2); num; num;对自增运算符的重载要区分前置和后置。在重载之前需要思考一个问题&#xff0c;num是返回一个临时变量还是num对象的本体。 为了解决这个问题可以考虑实现一个Inc_()函数和_Inc()函数分别模仿后置和前置的行为 Integer Inc_(){i…

YOLOv5算法改进(20)— 如何去写YOLOv5相关的论文(包括论文阅读+规律总结+写作方法)

前言:Hello大家好,我是小哥谈。最近一直在阅读关于YOLOv5的相关论文,读着读着我发现一条可以发论文的规律,特此简单总结一下,希望能够对同学们有所启迪!🌈 前期回顾: YOLOv5算法改进(1)— 如何去改进YOLOv5算法

IO文件操作

小王学习录 今日鸡汤文件一. 文件路径1. 绝对路径2. 相对路径二. 文件类型三. 文件操作1. 文件系统操作2. 文件内容操作(字节流)1. 读文件2. 写文件3. 释放资源(.close)3. 文件内容操作(字符流)重识(System.in)今日鸡汤 光阴如骏马加鞭, 日月如落花流水. 文件 狭义上的文件:…

欧拉图和哈密顿图

欧拉图 在连通图G中&#xff0c;经过G的每条边一次且仅一次的通路&#xff0c;称为欧拉通路若欧拉通路为回路&#xff0c;则称为欧拉回路含有欧拉回路的图称为欧拉图有欧拉通路则G可以一笔画出有欧拉回路则G是连通的且无奇点&#xff08;欧拉图无奇点&#xff09; 哈密顿图 …

【MATLAB源码-第56期】基于WOA白鲸优化算法和PSO粒子群优化算法的三维路径规划对比。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 1.粒子群算法&#xff08;Particle Swarm Optimization&#xff0c;简称PSO&#xff09;是一种模拟鸟群觅食行为的启发式优化方法。以下是其详细描述&#xff1a; 基本思想&#xff1a; 鸟群在寻找食物时&#xff0c;每只鸟都…

Kafka简单入门02——ISR机制

目录 ISR机制 ISR 关键概念 HW和LEO Java使用Kafka通信 Kafka 生产者示例 Kafka 消费者示例 ISR机制 Kafka 中的 ISR&#xff08;In-Sync Replicas&#xff09;机制是一种用于确保数据可靠性和一致性的重要机制。ISR 是一组副本&#xff0c;它包括分区的领导者&#xff…

【WinForm详细教程一】WinForm中的窗体、Label、TextBox及Button控件、RadioButton和CheckBox、ListBox

文章目录 1.WinForm文件结构2. 窗体的常用属性、方法与事件2.1 常用属性&#xff08;可直接在属性中设置&#xff09;2.2 常用方法2.3 常用事件 3.Label、TextBox及Button控件4.RadioButton和CheckBox5.ListBox&#xff08;列表框&#xff09; 1.WinForm文件结构 .sln文件 &am…

NFTScan | 10.16~10.22 NFT 市场热点汇总

欢迎来到由 NFT 基础设施 NFTScan 出品的 NFT 生态热点事件每周汇总。 周期&#xff1a;2023.10.16~ 2023.10.22 NFT Hot News 01/y00ts&#xff1a;迁移回以太坊的跨链桥已上线&#xff0c;将承担第一天所有 Gas 费 10 月 16 日&#xff0c;y00ts 发推称&#xff0c;将 y00…

scrapy的安装和使用

一、scrapy是什么&#xff1a;Scrapy是一个为了爬取网站数据&#xff0c;提取结构性数据而编写的应用框架&#xff0c;可以应用在包括数据挖掘&#xff0c;信息处理或存储历史数据等一系列的程序 二、scrapy的安装&#xff1a;pip install scrapy -i https://pypi.douban.com/…

vscode类似GitHub Copilot的插件推荐

由于GitHub Copilot前段时间学生认证的账号掉了很多&#xff0c;某宝激活也是价格翻了几倍&#xff0c;而却&#xff0c;拿来用一天就掉线&#xff0c;可以试试同类免费的插件哦。 例如&#xff1a;TabNine&#xff0c;下载插件后&#xff0c;他会提示你登录&#xff0c;直接登…

x-ui部署(与宝塔共存)

大家好&#xff0c;我叫徐锦桐&#xff0c;个人博客地址为www.xujintong.com。平时记录一下学习计算机过程中获取的知识&#xff0c;还有日常折腾的经验&#xff0c;欢迎大家来访。 x-ui是一个搭建节点的工具&#xff0c;有一键安装脚本&#xff0c;可以快速的部署。但是如果我…

分代ZGC详解

ZGC&#xff08;Z Garbage Collector&#xff09;是Java平台上的一种垃圾收集器&#xff0c;它是由Oracle开发的&#xff0c;旨在解决大堆的低延迟垃圾收集问题。ZGC是一种并发的分代垃圾收集器&#xff0c;它主要针对具有大内存需求和低停顿时间要求的应用程序 分代ZGC收集器…

JVM相关的面试题

一、什么是程序计数器 二、简要的介绍一下堆 三、什么是虚拟机栈 四、能不能解释下方法区 五、你听过直接内存吗&#xff1f; 六、什么是类加载器&#xff0c;类加载器有哪些 七、什么是双亲委派模型 八、JVM为什么采用双亲委派机制 九、类装载的执行过程 十、对象什么时候被垃…

粤嵌实训医疗项目day02(Vue + SpringBoot)

目录 一、创建vue项目并运行 二、vue-cli中的路由使用 三、element-ui框架、实现页面布局以及vue-路由 四、前端登录页面 五、user登录后端接口完善【后端】 六、user登录前端-请求工具-请求发起【前端】 七、请求的跨域-访问策略 八、完善项目的页面布局、导航菜单以及…

Nginx 防盗链

nginx防盗链问题 盗链&#xff1a; 就是a网站有一张照片&#xff0c;b网站引用了a网站的照片 。 防盗链&#xff1a; a网站通过设置禁止b网站引用a网站的照片。 nginx防止网站资源被盗用模块 ngx_http_referer_module 如何区分哪些是不正常的用户&#xff1f; HTTP Referer…

2023年信息科学与工程学院学生科协第一次前端培训

目录 一、前端是什么&#xff1f;前端能做什么&#xff1f;前端需要做什么&#xff1f;现阶段如何理解前端 二、前端学习路线html是什么&#xff1f;css是什么&#xff1f;什么是jshtml、css以及js关系掌握三种语言之后的学习路线 三、HTML基础语法标题段落文本换行文本标签图像…

Calibre拾遗:FDI (Foreign Database Interface)系统简介

Calibre是强大的GDS处理工具&#xff0c;包括查看&#xff0c;验证&#xff0c;分析等操作&#xff0c;操作由浅入深&#xff0c;除过手动编辑GDS的不是很灵活外&#xff0c;其他各种命令和操作策略&#xff0c;都是远&#xff08;遥&#xff09;远&#xff08;遥&#xff09;走…

视频去噪网络BSVD的实现

前些天写了视频去噪网络BSVD论文的理解&#xff0c;详情请点击这里&#xff0c;这两个星期动手实践了一下&#xff0c;本篇就来记录一下这个模型的实现。 这个网络的独特之处在于&#xff0c;它的训练和推理在实现上有所差别。在训练阶段&#xff0c;其使用了TSM&#xff08;T…

IP地址SSL证书 IP证书

在许多企业用例中&#xff0c;公司需要SSL证书作为IP地址。公司使用IP地址通过Internet访问各种类型的应用程序。 公网IP地址的SSL证书&#xff1a; 内部IP&#xff08;也称为私有IP&#xff09;是IANA设置为保存的IPv4或IPv6地址&#xff0c;例如&#xff1a; RFC 1918范围内…

【JavaEE】CAS -- 多线程篇(7)

CAS 1. 什么是 CAS2. CAS 伪代码3. CAS 是怎么实现的4. CAS的应用4.1 实现原子类4.2 实现自旋锁 5. CAS 的 ABA 问题 1. 什么是 CAS CAS: 全称Compare and swap&#xff0c;字面意思:”比较并交换“能够比较和交换 某个寄存器中的值和内存中的值, 看是否相等, 如果相等, 则把另…