UCOSIII实时操作系统------信号量以及优先级反转的问题

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

UCOSIII实时操作系统------信号量以及优先级反转的问题


提示:以下是本篇文章正文内容,下面案例可供参考

一、概述

信号量,Semaphore:英[ˈseməfɔː®]。
信号量常用于任务的同步,通过该信号,就能够控制某个任务的执行,这个信号具有计数值,因此,可以称为计数信号量。
计数信号量可以用于资源管理,允许多个任务获取信号量访问共享资源,但会限制任务的最大数目。访问的任务数达到可支持的最大数目时,会阻塞其他试图获取该信号量的任务,直到有任务释放了信号量。这就是计数型信号量的运作机制,虽然计数信号量允许多个任务访问同一个资源,但是也有限定,比如某个资源限定只能有 3 个任务访问,那么第 4 个任务访问的时候,会因为获取不到信号量而进入阻塞,等到有任务(比如任务 1)释放掉该资源的时候,第 4 个任务才能获取到信号量从而进行资源的访问,其运作的机制具体见下图。

在这里插入图片描述

二、PV原语

信号量S是一个整数,S大于等于零时代表可供并发进程使用的资源实体数,但S小于零时则表示正在等待使用临界区的进程数。

Dijkstra同时提出了对信号量操作的PV原语。
P原语操作的动作是:
  (1)S减1;
  (2)若S减1后仍大于或等于零,则进程继续执行;
  (3)若S减1后小于零,则该进程被阻塞后进入与该信号相对应的队列中,然后转进程调度。
V原语操作的动作是:
  (1)S加1;
  (2)若相加结果大于零,则进程继续执行;
  (3)若相加结果小于或等于零,则从该信号的等待队列中唤醒一等待进程,然后再返回原进程继续执行或转进程调度。

PV操作对于每一个进程来说,都只能进行一次,而且必须成对使用。在PV原语执行期间不允许有中断的发生。
信号量的P、V操作,P表示申请一个资源,每次P操作使信号量减1,V是释放一个资源,每次V操作使信号量加1。信号量表示的是当前可用的资源个数,当信号量为负时,申请资源的进程(任务)就只能等待了。所以,信号量是负的多少,就表明有多少个进程(任务)申请了资源但无资源可用,只能处于等待状态。
除了访问共享资源外,亦可中断/任务控制某任务的执行,称之为“单向同步”。

三、函数接口

1.创建信号量

void  OSSemCreate (OS_SEM      *p_sem,
                   CPU_CHAR    *p_name,
                   OS_SEM_CTR   cnt,
                   OS_ERR      *p_err)

参数
p_sem,信号量对象
p_name,信号量名字
cnt,信号量的初值
p_err,返回错误码,没有错误的就返回OS_ERR_NONE

2.等待信号量

OS_SEM_CTR  OSSemPend (OS_SEM   *p_sem,
                       OS_TICK   timeout,
                       OS_OPT    opt,
                       CPU_TS   *p_ts,
                       OS_ERR   *p_err)

参数
p_sem,信号量对象
timeout,超时时间,默认写0,一直等待
opt,设置当前等待互斥锁的阻塞方式,默认写OS_OPT_PEND_BLOCKING,阻塞等待
p_ts,用于记录等待信号量花了多长时间,默认写NULL,不记录。
p_err,返回错误码,没有错误的就返回OS_ERR_NONE

3.释放信号量

OS_SEM_CTR  OSSemPost (OS_SEM  *p_sem,
                       OS_OPT   opt,
                       OS_ERR  *p_err)

参数
p_sem,信号量对象
opt,信号量接收方
.OS_OPT_POST_1,只释放信号量给最高优先级且就绪的任务,类似于UDP的点播
.OS_OPT_POST_ALL,释放给所有等待信号量的任务,类似于UDP的广播

p_err,返回错误码,没有错误的就返回OS_ERR_NONE

返回值:
当前信号量计数值。

若多个任务等待信号量,等待信号量的任务最好是优先级是一样。

四、优先级反转

1.概述

优先级反转在可剥夺内核中是非常常见的,在实时系统中不允许出现这种现象,这样会破坏任务的预期顺序,可能会导致严重的后果,下图就是一个优先级反转的例子。
在这里插入图片描述
(1)任务H和任务M处于挂起状态,等待某一事件的发生,任务L正在运行。
(2)某一时刻任务L想要访问共享资源,在此之前它必须先获得对应该资源的信号量。
(3)任务L获得信号量并开始使用该共享资源。
(4)由于任务H优先级高,它等待的事件发生后便剥夺了任务L的CPU使用权。
(5)任务H开始运行。
(6)任务H运行过程中也要使用任务L正在使用着的资源,由于该资源的信号量还被任务L占用着,任务H只能进入挂起状态,等待任务L释放该信号量。
(7)任务L继续运行。
(8)由于任务M的优先级高于任务L,当任务M等待的事件发生后,任务M剥夺了任务L的CPU使用权。
(9)任务M处理该处理的事。
(10)任务M执行完毕后,将CPU使用权归还给任务L。
(11)最终任务L完成所有的工作并释放了信号量,到此为止,由于实时内核知道有个高优先级的任务在等待这个信号量,故内核做任务切换。

在这种情况下,任务H的优先级实际上降到了任务L的优先级水平。因为任务H要一直等待直到任务L释放其占用的那个共享资源。由于任务M剥夺了任务L的CPU使用权,使得任务H的情况更加恶化,这样就相当于任务M的优先级高于任务H,导致优先级反转。
优先级反转。简单地说,就是高优先级任务必须等待低优先级任务的完成。

2.解决方案

为了避免优先级反转这个问题,UCOSIII支持一种特殊的二进制信号量:互斥信号量,即互斥锁,用它可以解决优先级反转问题。
目前解决优先级反转有许多种方法。其中普遍使用的有2种方法:一种被称作优先级继承(priority inheritance);另一种被称作优先级天花板(priority ceilings)。
A. 优先级继承(priority inheritance) :优先级继承是指将低优先级任务的优先级提升到等待它所占有的资源的最高优先级任务的优先级。当高优先级任务由于等待资源而被阻塞时,此时资源的拥有者的优先级将会临时自动被提升,以使该任务不被其他任务所打断,从而能尽快的使用完共享资源并释放,再恢复该任务原来的优先级别。
B. 优先级天花板(priority ceilings): 优先级天花板是指将申请某资源的任务的优先级提升到可能访问该资源的所有任务中最高优先级任务的优先级。(这个优先级称为该资源的优先级天花板) 。
A和B的区别:优先级继承,只有当占有资源的低优先级的任务被阻塞时,才会提高占有资源任务的优先级;而优先级天花板,不论是否发生阻塞,都提升。
在UCOSIII,默认使用方案A,详细如下图。
在这里插入图片描述

五、注意事项

程序中可以使用任意多的信号量访问各种资源。比如一个信号量来访问一个共享的显示设备,另一个则访问一个共享的打印机;再用一个信号量来共享一些数据结构,另一个信号量来保护缓冲池等。不过一般建议信号量来访问I/O设备,而不用它来访问存储单元。
信号量常被用过了头,用信号量来处理简单的共享变量更是小题大做。请求和释放信号量的过程相当耗费时间的。尽管关中断可能会带来一些间接成本,甚至导致那些并不访问共享资源的高优先级任务也无法在第一时间被执行,但用户仍可以通过关中断、开中断来处理简单的共享变量从而提高整体工作效率。
例如两个任务共享一个32位的整数变量,一个任务给这个任务变量加1,另一个任务给这个变量清0。如果要求不管哪种操作,CPU都能在极短时间内完成,显然就不会使用信号量来满足互斥访问的条件了。每个任务只需要在操作这个任务之前关中断,之后再开中断就可以了。然而,如果这个变量是浮点数,而相应的微处理器又没有硬件的浮点协处理器,则浮点运算的时间相当长,如此一来,关中断时间长了便会影响到中断延迟,这种情况下就有必要使用信号量了。


总结

以上就是今天要讲的内容,本文仅仅简单介绍了UCOSIII实时操作系统------信号量以及优先级反转的问题,而UCOSIII实时操作系统还有更多的功能等着我们去挖掘,其他内容请移步博主其他文章或关注博主等待后续发布。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值