C 嵌入式系统设计模式 19:保护调用模式

本书的原著为:《Design Patterns for Embedded Systems in C ——An Embedded Software Engineering Toolkit 》,讲解的是嵌入式系统设计模式,是一本不可多得的好书。

本系列描述我对书中内容的理解。本文章描述嵌入式并发和资源管理模式之五:保护调用模式

保护调用模式 (Guarded Call Pattern) 是一种 任务协作模式。在软件设计中,任务协作模式是用于协调不同任务之间通讯和同步的策略。它旨在确保任务能够高效、有序地执行,并处理任务之间的依赖关系、优先级冲突和资源共享等问题。

保护调用模式用于 序列化 对某些服务的访问。当多个调用者同时调用这些服务时,可能会以某种方式产生干扰。所以不能直接调用这些服务,而是通过提供锁定机制来序列化访问,防止其他线程在锁定期间调用这些服务。具有这套保护机制的调用服务,称为 保护调用模式。简而言之,此模式通过 来确保同时只有一个线程能够使用特定资源或服务,从而避免潜在的并发问题

摘要

在抢占式多任务环境中,保护调用模式 使用 信号量 来保护一组相关的函数。这些函数组合起来提供某种 服务 。这样就能防止多个客户端同时访问这些服务,这个过程被称为 互斥

然而,如果不与其它模式混合使用,这种模式可能会导致不受控制的优先级翻转。

问题

该模式解决的是线程之间的同步或数据交换问题。在这种情况下,可能无法等待 异步会合,可以更及时地进行 同步会合 ,但必须小心进行,以避免数据损坏和计算错误。

异步同步 :异步是一种处理并发操作的方法,允许程序在等待某些操作完成(如 I/O 操作)的同时,继续执行其他任务。这种方法与同步操作相对,同步操作会阻塞程序执行,直到等待的操作完成为止。比如,用 队列 来实现异步,用函数调用来实现同步。

会合 :即同步点,任务的动作序列中的一个特定动作,任务会在此等待,直到其他任务也达到相应的同步点。

在异步环境中,线程之间的会合可能是不确定的,因此等待异步会合可能不是一种可靠或高效的方法。因此书中说 保护调用模式 可能不适用于异步会合。

模式结构

模式结构如下图所示:

在这里插入图片描述
在这种情况下,多个 抢占式任务(PreemptiveTasks)通过资源模块提供函数访问 受保护资源(GuardedResource)。在这些函数内部,会调用 锁定释放 资源的操作。调度器支持阻塞,当任务调用已被锁定的信号量时,将其放置在阻塞队列中,并在该信号量释放时解除其阻塞。调度器必须将信号量的 lock() 函数实现为 临界区,以消除竞态条件的可能性。

模式详情

受保护的资源

受保护的资源 是一个共享资源,它使用互斥信号量来保护自己提供的函数,强制调用者互斥访问。在它提供的函数内部,当访问之前,会调用关联的 信号量 实例的 lock() 函数。如果信号量处于未锁定状态,则该资源被锁定;如果资源已处于锁定状态,则信号量会通知 静态优先级调度器 阻塞当前正在运行的任务。重要的是,特定资源实例的相关函数必须共享同一个信号量类的实例。这确保了它们作为一个单元受到保护,防止多个 抢占式任务 同时访问。

特定资源实例的相关函数必须共享同一个信号量类的实例:这是确保资源正确保护的关键。如果每个函数都有自己的信号量实例,那么它们就无法有效地协调对共享资源的访问。相反,通过共享同一个信号量实例,它们可以确保在任何时候只有一个任务能够访问该资源。

抢占式任务

抢占式任务 表示一个通过抢占式多任务调度器运行的任务。它通过调用 受保护的资源 的函数来访问该资源,而这些函数又受到信号量的保护。这样确保了抢占式任务在访问受保护的资源时不会受到其他任务的干扰,从而保证了数据的一致性和系统的稳定性。

信号量

这里 信号量 使用的是互斥信号量,用于 序列化受保护的资源 的访问。受保护的资源的受保护函数在被调用时会调用信号量的 lock() 函数,并在服务完成后调用 release() 函数。当关联的信号量被锁定时,尝试调用服务的其他客户端线程将被阻塞,直到信号量解锁。这个元素通常由 RTOS(实时操作系统)提供。

效果

保护调用模式提供了对资源的及时访问,并通过锁定机制防止了多个同时访问,这些同时访问可能会导致数据损坏或系统错误行为。当资源未被锁定时,访问可以立即进行,没有任何延迟,从而保证了系统的实时性。如果资源被锁定,调用者必须等待锁释放,这可能导致调用者被阻塞一段时间。然而,如果不当地使用这种模式,可能会导致不受控制的优先级反转。

实现策略

实现 保护调用模式 的关键部分在于 互斥量 的实现。通常,RTOS 会提供这个信号量(互斥量是信号量的一种)。一般会有以下操作:

  1. 创建一个信号量
  2. 销毁一个信号量
  3. 锁定信号量
  4. 释放信号量

相关模式

保护调用模式在抢占式多任务环境中使用,比如使用 静态优先级调度器 的环境。与 临界区模式 相比,它不会干扰不需要访问资源的更高优先级任务的执行;与 队列模式 相比,它响应更迅速,因为当资源有效时,操作系统会解除等待资源的任务。

这个模式有一类非常重要的变体,它使用 优先级继承 的概念来解决 不受控制的优先级反转 的问题。基本思想是,每个资源都有一个额外的属性(变量),称为优先级上限(priority ceiling),它等于能够访问该资源的最高优先级任务的优先级。

注:实际上,目前主流的 RTOS 提供的互斥量都是具有优先级继承的。

为什么要使用具有优先级继承的互斥量来实现保护调用模式?

不使用具有优先级继承的互斥量来实现保护调用模式,称为 原始的保护调用模式 ,它存在一个根本的问题是:会产生不受控制的优先级反转 问题。即,不需要该资源的中等优先级任务可以抢占当前拥有被阻塞的高优先级任务所需资源的低优先级任务。这样的中等优先级任务可能有任意多个,导致高优先级任务被连锁阻塞。这句话可能很绕,我来举一个例子:

如下图所示,任务 A 和任务 Z 会使用资源 R ,而任务 X 和任务 Y 并不直接使用资源 R,但它们会影响任务 A 和任务 Z 的执行。
在这里插入图片描述
最坏情况如下所示:

  1. 任务 Z 首先运行并锁定了资源 R。
  2. 任务 A 开始运行,任务 A 优先级更高,它立即抢占任务 Z。任务 A 运行到需要访问资源 R 的时候,因得不到资源 R 而被阻塞。
  3. 此时,任务 Z 继续运行
  4. 但紧接着任务 Y 开始运行,由于任务 Y 优先级高于任务 Z,因此它立即抢占任务 Z。
  5. 在任务 Y 运行期间,任务 X 变得可以运行,并且由于任务 X 的优先级高于任务 Y,因此它立即抢占任务 Y。

这样,任务 A 被三个低优先级的任务(Z、Y 和 X)所阻塞,无法访问所需的资源 R。

由于任务 Y 和任务 X 的执行,最坏情况下任务 A 需要 190 ms ( 任务 Z 锁定资源 10 ms + 任务 Y 执行时间 100 ms + 任务 X 执行时间 80 ms)才能获得资源 R 。这导致了任务 A 错过其截止时间,因为它无法在 50ms 的周期内完成任务。这种现象称为 不受控制的优先级反转 ,是一个严重的问题,因为它可能导致高优先级任务无法及时完成,从而影响系统的实时性能和可靠性。

还是上面图中所示的情况,我们再来看一下使用 优先级继承 机制后,带来的变化:

  1. 任务 Z 首先运行并锁定了资源 R。
  2. 任务 A 开始运行,任务 A 优先级更高,它立即抢占任务 Z。任务 A 运行到需要访问资源 R 的时候,因得不到资源 R 而被阻塞。此时,任务 Z 的优先级会被 提升 到任务 A 的优先级,即优先级为 1
  3. 此时,任务 Z 继续运行
  4. 紧接着,任务 Y 处于就绪状态,但是由于任务 Z 的优先级已经提升到和任务 A 相同的优先级,因此任务 Y 无法抢占任务 Z 的执行
  5. 相同的原因,就绪状态的任务 X 同样无法抢占任务 Z 的执行
  6. 任务 Z 完成了对资源 R 的使用并解锁了它。在优先级继承机制下,当任务Z释放资源R时,它的优先级将从提升的优先级(=1)降低回其原始优先级(=99)。
  7. 任务 A 会立即解除阻塞,并获得资源 R 的使用权。任务 A 可以在截止时间之前完成任务。

通过这个简单的例子,我们可以看到优先级继承如何防止了不受控制的优先级反转的问题,这是普通的计数信号量所无法避免的。

实例

见原书。






读后有收获,资助博主养娃 - 千金难买知识,但可以买好多奶粉 (〃‘▽’〃)
千金难买知识,但可以买好多奶粉

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

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

相关文章

Cesium 3D Tiles 简介

3D Tiles 是大规模异构 3D 地理空间数据集(例如点云、建筑物和摄影测量)的开放标准。3D Tiles 基于 glTF 和其他 3D 数据类型构建,是一种可类似二维瓦片模式的流式传输的优化格式,旨在适应当今不断增长的 3D 地理空间数据集的渲染…

编码规范(前端)

文章目录 1. 文档说明1.1 编制说明1.2 名词解释 2.前端研发规范2.1 HTML编码规范2.1.1 文档类型2.1.2 语言2.1.3 元数据2.1.4 资源加载2.1.5 页面标题2.1.6 编码风格2.1.7 标签2.1.8 属性2.1.9 语义化 2.2 CSS编码规范2.2.1 文件引用2.2.2 命名-组成元素 知识点 1. 文档说明 1…

【数据分享】1979~2020年MSWEP降水数据集

各位同学们好,今天和大伙儿分享的是1979~2020年MSWEP降水数据集。如果大家有下载处理数据等方面的问题,您可以私信或者评论。 Beck, H. E., E. F. Wood, M. Pan, C. K. Fisher, D. G. Miralles, A. I. J. M. van Dijk, T. R. McVicar, and R. F. Adler, …

【软件设计师】通俗易懂的去了解算法的特性和要求

🐓 算法 算法是对特定问题求解步骤的一种描述,算法是指令的有限序列。其中每一条指令表示一个或者多个操作。 🐓 算法的5种属性 有穷性 一个算法必须总是在执行有穷的步骤后,且在每个步骤执行的过程中时间是有限的 1.有穷性意味…

深度学习 精选笔记(7)前向传播、反向传播和计算图

学习参考: 动手学深度学习2.0Deep-Learning-with-TensorFlow-bookpytorchlightning ①如有冒犯、请联系侵删。 ②已写完的笔记文章会不定时一直修订修改(删、改、增),以达到集多方教程的精华于一文的目的。 ③非常推荐上面(学习参考&#x…

蓝桥杯:单词分析

题目 题目描述 小蓝给学生们组织了一场考试,卷面总分为 100 分,每个学生的得分都是一个 0 到 100 的整数。 如果得分至少是 60 分,则称为及格。如果得分至少为 85 分,则称为优秀。 请计算及格率和优秀率,用百分数表…

Rstudio-深度学习执行代码

RStudio是一个开源的集成开发环境(IDE),专门用于R编程语言的开发和数据分析。R语言是一种流行的统计计算和数据可视化语言,广泛用于数据科学、统计学和机器学习领域。 RStudio提供了许多功能强大的工具,包括代码编辑器…

SQL 基本条件查询DQL 练习

DQL DQL(Data Query Language)是SQL语言中的一种类型,用于执行数据查询操作。它是SQL的一部分,用于从数据库中检索数据。DQL语句用于从一个或多个表中选择、过滤和排序数据。常见的DQL查询语句包括SELECT、FROM、WHERE、GROUP BY…

U盘无法读取?轻松掌握正确解决方法!

“为什么我的u盘插入电脑后会显示无法读取呢?想查看一些比较重要的文件,但就是无法读取U盘,想问问大家,我应该怎么操作呢?” U盘作为一种便捷的数据存储设备,广泛应用于我们的日常生活和工作中。然而&#…

独立游戏《星尘异变》UE5 C++程序开发日志2——创建并编写一个C++类

在本篇日志中,我们将要用一个C类来实现一个游戏内的物品,同时介绍UCLASS、USTRUCT、UPROPERTY的使用 一、创建一个C类 我们在UE5的"内容侧滑菜单"中,在右侧空白中右键选择"新建C类",然后可以选择一个想要的…

python70-Python的函数入门,了解下函数

函数是执行特定任务的一段代码,程序通过将一段代码定义成函数,并为该函数指定一个函数名,这样即可在需要的时候多次调用这段代码。因此,函数是代码复用的重要手段。学习函数需要重点掌握定义函数、调用函数的方法。 与函数紧密相关的另一个知识点是lambda表达式。lamda表达…

Spring AOP(Aspect-Oriented Programming,面向切面编程)介绍

Spring AOP(Aspect-Oriented Programming,面向切面编程)是Spring框架的一个重要模块,它提供了一种强大的方式来帮助开发者实现横切关注点(cross-cutting concerns)的模块化。横切关注点是指那些影响多个模块…

Linux设备模型(十一) - platform设备

一,platform device概述 在Linux2.6以后的设备驱动模型中,需关心总线、设备和驱动这3个实体,总线将设备和驱动绑定。在系统每注册一个设备的时候, 会寻找与之匹配的驱动;相反的,在系统每注册一个设备的时…

【Redis】实际应用 - 缓存

文章目录 1. 缓存的基本概念2. Redis作为缓存的优势2.1 内存存储2.2 持久性选项2.3 数据结构丰富 3. Redis缓存的使用3.1 安装和配置Redis3.2 连接到Redis3.3 存储和获取数据3.4 设置过期时间 4. 缓存策略4.1 LRU(最近最少使用)4.2 数据失效4.3 主动刷新…

可让照片人物“开口说话”阿里图生视频模型EMO,高启强普法

3 月 1 日消息,阿里巴巴研究团队近日发布了一款名为“EMO(Emote Portrait Alive)”的 AI 框架,该框架号称可以用于“对口型”,只需要输入人物照片及音频,模型就能够让照片中的人物开口说出相关音频&#xf…

PDN分析及应用系列二-简单5V电源分配-Altium Designer仿真分析-AD

PDN分析及应用系列二 —— 案例1:简单5V电源分配 预模拟DC网络识别 当最初为PCB设计打开PDN分析仪时,它将尝试根据公共电源网络命名法从设计中识别所有直流电源网络。 正确的DC网络识别对于获得最准确的模拟结果非常重要。 在示例项目中已经识别出主DC网络以简化该过程。 …

Vulnhub靶机:Bellatrix

一、介绍 运行环境:Virtualbox 攻击机:kali(10.0.2.4) 靶机:Bellatrix(10.0.2.9) 目标:获取靶机root权限和flag 靶机下载地址:https://www.vulnhub.com/entry/hogwa…

Leetcode 3070. Count Submatrices with Top-Left Element and Sum Less Than k

Leetcode 3070. Count Submatrices with Top-Left Element and Sum Less Than k 1. 解题思路2. 代码实现 题目链接:3070. Count Submatrices with Top-Left Element and Sum Less Than k 1. 解题思路 这一题就是一个二维的累积数组的问题,我们直接求一…

网络学习:MPLS技术基础知识

目录 一、MPLS技术产生背景 二、MPLS网络组成(基本概念) 1、MPLS技术简介:Multiprotocol Lable Switching,多协议标签交换技术 2、MPLS网络组成 三、MPLS的优势 四、MPLS的实际应用 一、MPLS技术产生背景 1、IP采用最长掩码…

Power BI vs Superset BI 调研报告

调研结论 SupersetPower BI价格开源①. Power BI Pro 每人 $10/月($120/年/人) ②. Power BI Premium 每人 $20/月($240/年/人) ③. Power BI Embedded:4C10G $11W/年 权限基于角色的访问控制,支持细粒度的访问: 表级别、库级别、图表级别,看板级别,用户级别 基于角色…