UcosII 共享资源的锁机制的处理

xiaoxiao2021-02-28  84

                使用Ucosii操作系统编写应用程序时,会经常使用到全局变量等共享资源。若在使用时,如对全局变量的同时的读写操作,可能会造成程序的崩溃,故在使用全局变量时,要对其进行锁或互斥处理。另,如果函数可以进行修改,则可通过函数的可重入性,即传形参使用局部变量,而避免使用全局变量。

共享资源处理简介:

(1)关中断/开中断          关、开中断是独占共享资源最简单也是最快捷的方法。μC/OS-Ⅲ访问系统内部的变量和数据结构时,绝大部分使用的就是这种方法,一次来确保操作的“原子性”。这种方法也是任务和中断服务程序共享变量或数据结构的唯一方法。          使用这种方法时,只要关中断时间比系统本身关中断时间短(或相同),就不会增加中断延迟。然而尽管如此,仍要尽量避免关中断,因为这将影响到系统对实时事件的响应能力。

 (2)给调度器上锁/解锁          如果任务不需要和中断服务程序共享变量或数据结构,那么可以通过给调度器上锁的方法来访问共享资源。需要注意的是,一旦给调度器上锁,即使有更高优先级的任务就绪了,也要等当前任务执行完毕,解锁后才能切换到其他任务。也就是说一旦某个任务给调度器上锁,那这个任务就成为了优先级最高的任务。 

(3)信号量          信号量是一种上锁机制,代码必须获得对应钥匙(解锁)才能继续执行。信号量一共有6个相关API函数: 

1、OSSemCreat()         ---建立一个信号量 

2、OSSemDel()             ---删除一个信号量 

3、OSSemPend()          ---等待一个信号量 

4、OSSemPendAbort() ---取消等待 

5、OSSemPost()            ---释放或者发出一个信号量 

6、OSSemSet()              ---强制设置一个信号量的值        

针对不同的情况一共有两种信号量。 

1、二进制信号量        当一个资源只有两种状态时(空闲、被占用),则使用此信号量。二进制信号量非0即1,当任务间共享变量、单一IO设备时可使用此信号量。 

2、计数型信号量        计数型信号量用于某资源可同时被几个任务使用的情况。例如某个缓冲池(Buffer)有10个缓冲块,任务可以申请其中一个缓冲块,此时可使用技术型信号量,且信号量初始值被设置为10。当信号量为0时,表示缓冲区满,需要等待。        

信号量是一个os_sem类型数据,包含5个成员:

1、Type          ---存储变量类型; 

2、*NamePtr---存储用户给该变量定义的名字,用于调试; 

3、PendList   ---该信号量的任务挂起表; 

4、Ctr            ---信号量的计数器成员; 

5、TS             ---时间戳,记录信号量上一次被释放的时间。          优先级反转是使用信号量要特别注意的问题,假设有两个不同优先级的任务同时使用一个信号量,介于两个优先级之间还有一个优先级的任务要运行,若高优先级任务需要等待低优先级任务释放信号量,则此时在任务调度过程中,会将高优先级任务挂起,首先执行中等优先级任务,然后执行低优先级任务,待低优先级任务释放信号量后,再执行高优先级任务。此时高优先级任务已经降到和低优先级任务相同的优先级。在使用信号量时要特别注意这种情况。     

(3)互斥型信号量         互斥型信号量是一种特殊的二进制信号量,其与普通信号量唯一的不同在于一旦一个高优先级的任务需要依赖低优先级任务发布信号量,则将低优先级任务的优先级暂时提高到与高优先级任务相同的优先级,带信号量发布完成后,再恢复其优先级。  互斥型信号量有5个API函数: 

1、OSMutexCreate()        ---建立一个互斥型信号量 

2、OSMutexDel()             ---删除一个互斥型信号量 

3、OSMutexPend()          ---等待一个互斥型信号量 

4、OSMutexPendAbort()---取消等待  

5、OSMutexPost()           ---释放或发布一个互斥型信号量 

互斥型信号量是一个os_mutex类型数据,包含7个成员: 

1、Type          ---存储变量类型; 

2、*NamePtr---存储用户给该变量定义的名字,用于调试; 

3、PendList   ---该信号量的任务挂起表; 

4、*OwnerTCBPtr---如果互斥型信号量被一个任务占用,则该成员保存该任务的OS_TCB。  5、OwnerOriginalPrio---记录任务占有互斥型信号量之前的优先级。 

6、Ctr            ---μC/OS-Ⅲ允许任务多次嵌套“获取”互斥型信号量,但是释放次数必须和获取次数一样多。 

7、TS             ---时间戳,记录信号量上一次被释放的时间。 

二、死锁          死锁(deadlock)也叫做抱死(deadly embrace),指两个任务无限制地相互等待对方控制着的资源。          假设某一时刻,任务A获取资源X,任务B获取资源Y,运行一段时间后,任务A和任务B均未释放资源,此时任务A试图获取资源Y,任务B试图获取资源X,则发生死锁。 

避免死锁的方法有三种: 

1、先得到全部需要的资源,再做下一步工作; 

2、用相同的顺序申请多个资源; 

3、在调用请求信号量的函数中设定超时时间,该方法仅可以暂时缓解,但是有可能导致死锁重复出现多次。 

上述三个方法中,个人建议严格按照方法2来避免死锁。

转载请注明原文地址: https://www.6miu.com/read-28060.html

最新回复(0)