信号量保护之位带操作

大家好,上篇文章写的一个中断操作变量的问题,鱼鹰帮忙回复了,大家可以再看看这篇文章。

66cf6bda1ec83a9b43667fbd73cca0ec.jpeg

好友让我看这段代码

CM3位带操作

如果存储器系统支持“锁定传送”( lockedtransfers),或者总线上只有一个主机,还可以使用CM3的位带功能来实现互斥锁的操作。通过使用位带,则可以在C程序中实现互斥锁,但是操作过程与互斥访问是不同的。在使用位带来做资源分配的控制机制时,需要使用位带存储区的内存单元(比如,一个字),该内存单元的每个位表示资源正被特定的任务使用。在位带别名区的读写实质上是锁定的“读‐改‐写”(在传送期间总线不能被其它主机占有)。因此,只要每个任务都仅修改分配给它们自己的锁定位,其它任务锁定位的值就不会丢失,即使是两个任务同时写自己的锁定位也不怕,如图:

9c5d1872f4e6317b00c8364a92544da6.jpeg                          

以两个任务为例,看如下情况:(红色箭头代表跳转执行)

78f4c6ecec8f46c5b8e2e984073b2c47.jpeg

任务2首先读取并判断,之后因某种原因跳转到任务1执行读取、判断、设置操作,又因为某种原因在设置完之后又跳转到任务2去进行设置、读取操作,后来又到任务1去执行读取并判断操作,发现有其它位置1,则放弃该资源,然后当运行任务2时,因为还是之前的数据,所以认为最终的判断认为有其它任务占用,也放弃该资源。最终的结果就是两个任务都放弃了该资源。但这种情况很少见,因为这需要在几条指令中来来回回跳转才会发生这种情况,一般情况是整个操作流程只会被其它任务中断一次。

再来分析以下执行流程,任务1在读取完之后任务2设置了占用标志,然后回到任务1判断,结果就是任务1占用资源,即使后续又被任务2中断了,任务2也是会读取到任务1的占用标志,从而放弃资源。

91cdc7d4f7a22582c2591b7aec7203df.jpeg

以下是中断判断操作(判断未执行)之后可能跳转的位置,自行分析(关键在于设置)。

f090c0eac559d60fe03b50bef4fe8d29.jpeg

那么位带别名操作避免的是什么呢?其实就是用于避免读-改-写的操作中因为中断,导致其它任务设置的数据因为最后写的步骤而丢失了。如下:

a470edbecfde302b1457e6a15e4ade6f.png

因为在设置的时候发生中断,导致任务2设置,但是因为中断的是设置操作,所以当回到设置的时候,读取的数据还是之前的数据,此时再进行设置操作必然导致任务2的设置操作丢失,并最终导致严重后果。

再深入思考后发现这些操作的关键在于你设置标志后判断你是否真的拥有该资源。那是否可以将前面的读取判断操作省去而直接去设置该标志呢?我认为是可以的,但是这里有一个缺点就是因为你不管有没有其它任务设置标志都自己去设置,一旦在有其他任务设置的情况下设置标志,你就必须进行清除自己标志的操作,加上你之前设置的操作,明显比先判断之后再进行设置操作效率更低。

那么是不是说如果没有位带操作就没办法进行互斥访问呢?当然不是,简单的方法是关中断的方式,但通过先前的分析发现,其实关键点在于别破坏其他设置的标志即可,这样我们可以把字节当位来看也是可以的,你设置你的字节标志,我设置我的字节标志,互不干扰,一样可以达到位带操作的效果,只是空间占用更大一些罢了。但是单片机最大的读取类型是double型数据,在stm32中即为8字节,也就是说可设置的最大任务数就是8个任务,而位带操作为8*8=64个任务,但是是否可以采用多次判断的方式增加任务数呢?比如两个double组合使用时利用两次判断两个变量的方法确定是否占用资源。这是一个解决方法,但是这个方法是否存在风险呢?通过后面的分析其实可以得到答案。

再进行深入思考之后,你就会发现,最为关键的就是设置之后的“读取”这个确认操作,这个操作是整个资源锁定操作的分水岭。在整个操作流程中,不管哪个操作被中断,然后被其它任务设置标志位,关键都在读取这一步,谁将变量读取到寄存器时没有其他任务设置标志位中,谁就占用了资源。

两个任务在宏观上可以认为在同时执行,但是在执行读取操作的时候,如果两个任务同时进行到了这一步,必然有一个先后(不管谁先谁后,,只要对方没有在你读取前放弃占用,都会放弃占用,而如果说真存在同时读取(两个cpu)的情况,那么必然是同时放弃资源的结果)。既然已经执行到了读取操作,那么就必然进行了设置操作,也就是说两个人同时设置了标志位,都准备占用资源,不管谁进行读取,最终的结果就是资源已经被占用,之后就是放弃了,即使任务在在读取后马上被中断判断的操作,但却不会影响该任务后续的判断、放弃操作了,因为你读取的数据已经决定了该任务的所有后续操作,所以关键操作就是读取操作,你读取的到底是什么数据。

那么最糟糕的情况就如前面所说,两个任务的在读取之后都发现被其他任务占用,然后都放弃资源,然后我们再分析其他可能性,两个任务的读取的数据理论上有四种可能,11,10,01,00。但是实际上00是可以排除的,因为读取之前必然已经进行了设置,那么除了

该任本身的标志位外只有其他任务可能设置的标志位了,即要么设置,要么没设置。如果设置了,又分为两种情况,如果另一个任务已经放弃了占用,那么它就可以占用资源,如果该任务在读取之前另一任务没有放弃资源,那么就放弃资源。

用图表示可能更清晰一些:

2a7076754a42b5a271750c6a45b4b378.jpeg

其实进行深入分析之后可以发现,就是之前所说的两个关键操作它们的先后顺序,而决定是否占用资源的关键操作就是读取操作。谁先读取到没有其他任务占用的情况谁就占用了该资源。

现在再来考虑有没有可能出现两个任务读取操作之后发现对方都没请求占用资源而同时占用资源的情况?我们知道互斥操作为的就是避免这种情况而特意设定的操作流程,如果这种情况不能避免分析再多都没用。事实上这种情况是不可能出现的,因为一个任务在读取的时候这个任务已经设置完本任务的标志位了,一旦读取之前另一个任务没有设置标志位,就算是占用了资源,然后另一任务在读取的时候必然是有任务占用的结果,就会放弃占用,就不会存在这个任务读取时没任务占用,另一个任务读取的时候也没占用,因为同一时间只能有一个任务先进行读取操作,不可能同时,即使是同时进行读取操作,最终的结果也只是同时放弃资源罢了。也就是说在在设置操作后给了任务两种可能性,占用或不占用,同时也避免了两个任务同时占用的情况。

所以之前的遗留的问题答案是不会有风险,因为最糟糕的情况也只是两个任务同时放弃资源。

总之一句话,谁读取时没其他任务占用,不管后面发生什么情况,这个资源我占定了。

---------------------------------------------------------------------------------------2018-08-18Osprey

在上面的互斥量问题的思考中,我们可以得出一个结论,读取的数据是什么决定了你接下来的动作是什么,并且按照先前的探讨可以发现即使不关闭总中断也不会导致资源使用的混乱问题,正是基于此考虑,认为很多情况下是可以不关闭中断的,但是当我看到如下uCOS II源码的时候,认为不关闭中断也是可以的,但是进行深入思考发现必须关闭中断才行。

bed4112f3c95d4bd5397e92a9905e792.jpeg

看如上消息邮箱OSMboxPend的源码,可以发现在读取消息指针的时候就关闭了中断,但是按照先前的思考,即使没有关闭中断,大不了在读取过程中被中断,然后将OSEventPtr设置为非零状态。但是不会影响后面的判断操作,但是真的如此吗?

fc12ad837a73b0063c3611d4000c9a8d.png

从上面两种情况分析可以发现,在不关闭中断的情况下确实可以保证判断语句正确执行(这里假设pmsg = pevent->OSEventPtr;这条C语言语句需要3条汇编语句操作执行),但是最终根据读取的pmsg值进行判读后的结果却会导致两种截然不同的效果。一个是直接返回,当前任务正常执行,另一种情况是将当前任务设置为等待状态,除此之外可能还会有影响整个系统混乱的操作,这是绝对不允许的情况。

在之前分析共享资源的互斥量时发现也会出现这种情况,但是为什么却不会没事呢?这是因为最糟糕的情况就是都获取不到共享资源,而一般来说都获取不到资源的虽然少见,但在之前那种不管中断操作的情况下确实会出现,但是即使都获取不到资源也不会导致系统严重后果,因为一般来说,当自己没有获取到资源的时候,下次还会继续尝试获取,另一个任务同样如此,在不管中断的情况下,只是导致重新获取资源的话,这是可以接受的一种情况。但是现在分析的这种情况却不允许,因为本来能正常运行的,你却让它进入等待状态,很可能导致严重的后果。所以在判断问题上,如果打断判断的不同结果会导致非常严重的后果,那么最好将读取、判断、分类动作设置成原子操作(不可打断的操作),而将整个流程设置成原子操作的一般方法就是关中断。

--------更新2018/08/23 Osprey

3990e76a6223f3fda05667756daf64e8.jpeg

f6ee60fd98be6adcf61d21ff0c3c761d.gif

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

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

相关文章

LeetCode872. Leaf-Similar Trees

自己的代码: # Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val x # self.left None # self.right Noneclass Solution:def allNode(self,root):listNode[]if Not root:return ListNode…

CCScene切换的所有特效(28种)以及设置屏幕横竖屏!

CCScene 对于使用cocos2d的童鞋肯定很熟悉,那么在使用 CCScene *s [CCScenenode];[s addChild: [restartAction() node]];[[CCDirectorsharedDirector]replaceScene:s]; 对scene进行场景(CCLayout)进行切换时,cocos2d提供了一…

关于MySqlConnection的一个特殊异常

最近给一个客户做一个项目,其中要与另外一个系统进行数据交换,而那个系统使用的是MySql,因此,从网上下载了一个MySql Connector,由于以前没有用过MySql,而且这个MySql服务器位于互联网上,因此&a…

文档设置及使用

原文链接:http://stynzf.blogbus.com/logs/15944928.html在上一篇文档(《微软文档管理解决方案2007》之一:安装部署)中,讲述了如何安装部署“文档管理解决方案” 这次我们通过将该子网站作为“Windows中文站”的一个文…

SSL和HTTPS

SSL说明: 1)简介 SSL (Secure Socket Layer)为Netscape所研发,用以保障在Internet上数据传输之安全,利用数据加密(Encryption)技术,可确保数据在网络上之传输过程中不会被截取。它已被广泛地用于Web浏览器与服务器之间…

N32替换STM32,这些细节别忽略!

前言目前大形势影响,芯片价格日益上涨,采购周期变长,导致国产芯片替代进口芯片成为大趋势,该文章记录了使用国民技术的N32替换STM32的操作流程。话不多说,上步骤。一、工程配置1.安装硬件库硬件库为厂家提供的资料&…

五分钟读懂UML类图

平时阅读一些远吗分析类文章或是设计应用架构时没少与UML类图打交道。实际上,UML类图中最常用到的元素五分钟就能掌握,下面赶紧来一起认识一下它吧: 一、类的属性的表示方式 在UML类图中,类使用包含类名、属性(field) 和方法(meth…

黑马程序员——java语言基础——面向对象

---------------------- android培训、java培训、期待与您交流! ---------------------- 类就是:对现实生活中事物的描述。 对象:就是这类事物,实实在在存在个体。 描述事物其实就是在描述事物的属性和行为。 如何定义类————…

只会纯硬件,让我有点慌

纯硬件产品在市面上现在很少了,大多都带有单片机,比如智能路灯,智能门禁,智能家居等等。为了提高竞争力,单片机相关知识的学习必不可少。给大家推荐一本龙顺宇老师的新书《深入浅出STC8增强型51单片机进阶攻略》。&…

Expression Blend 学习视频下载

微软Expression Blend功能介绍Microsoft Expression Blend—一个全新的,全功能的职业设计工具,用于创造基于Microsoft Windows平台的丰富、复杂的应用界面。使用 Expression Blend, 可以提供更出色的应用软件并提升客户的体验和满意度。Expression Blend…

1、绪论初识机器学习

什么是机器学习? 机器学习是通过数据或者经验,优化计算机程序等性能标准,自动改进计算机的算法,以达到解决未知问题的目标 监督学习 计算机通过学习一组有标签的信息来对从未见过对数据做出有用对预测 监督学习的代表算法&#xf…

NSLog的常用格式说明小释

NSLog的格式如下所示: % 对象%d, %i整数%u 无符整形%f 浮点/双字 %.nf 带有n小数点的浮点/双字%x, %X二进制整数%o 八进制整数%zu size_t %p 指针%e 浮点/双字 (科学计算) %g 浮点/双字%s C字符串%.*s Pascal字符串%c 字符%C unichar %lld 64位长整数(long long) %llu 无符64位…

感觉自己好傻

前几天,一个微信微信朋友找我聊天。他在一家公司工作了4年多,但是这四年基本没有什么技术上的提升,做的事情也一些打杂的事情,核心技术在芯片原厂,软件SDK也是别人写好的,他能做的就是对接客户,…

一名老工程师的感言

[1]好好规划自己的路,不要跟着感觉走!根据个人的理想决策安排,绝大部分人并不指望成为什么院 士或教授,而是希望活得滋润一些,爽一些。那么,就需要慎重安排自己的轨迹。从哪个行业入手,逐 渐对该…

Python之OS模块进程管理介绍--os.fork()

转自:http://davidbj.blog.51cto.com/4159484/1240586 有两种方式来实现并发性,一种方式是让每个“任务"或“进程”在单独的内在空间中工作,每个都有自已的工作内存区域。不过,虽然进程可在单独的内存空间中执行,…

洛谷 P1272 重建道路

题目链接 题解 树形dp \(f_{i, j}\)表示以\(i\)为根的子树切出联通块大小为\(j\)的最小答案 显然\(f[i][1]\)为与\(i\)连的边数 设\(v\)是\(u\)的儿子 那么有\(f[u][i]f[u][i-j]f[v][j]-2\)&#xff0c;因为\(u->v\)这条边算了两次 注意\(i\)要从大到小枚举Code #include<…

网盘是否能做一只安全的企业信息快递手

近期&#xff0c;某电商网站出现的用户账户被盗刷事件再次将信息安全问题推至风头浪尖之上。事实上&#xff0c;需要信息安全感的&#xff0c;不单单是个人&#xff0c;企业更甚。据悉&#xff0c;对安全规则和数据泄露的担忧成为了目前企业采纳云存储平台的重要障碍。 网盘&am…

图形处理单元(GPU)的演进

CPU 和 GPU好久没有更新了&#xff0c;最近在阅读 CUDA 相关的一些论文&#xff0c;因为都是碎片化阅读&#xff0c;容易导致读过后&#xff0c;可能过一段时间又忘记掉&#xff0c;所以决定抽时间翻译翻译阅读的论文&#xff0c;一方面增强自己记忆&#xff0c;一方面与大家共…

TCP通信过程大讨论

转载地址&#xff1a;http://www.cricode.com/3568.html 本文通过两个图来梳理TCP-IP协议相关知识。TCP通信过程包括三个步骤&#xff1a;建立TCP连接通道&#xff0c;传输数据&#xff0c;断开TCP连接通道。如图1所示&#xff0c;给出了TCP通信过程的示意图。 图1 TCP 三次握手…

Stream、FileStream、MemoryStream的区别

1.Stream&#xff1a;流&#xff0c;在msdn的定义&#xff1a;提供字节序列的一般性视图&#xff0c;Stream提供了读写流的方法是以字节的形式从流中读取内容。而我们经常会用到从字节流中读取文本或者写入文本&#xff0c;微软提供了StreamReader和StreamWriter类帮我们实现在…