UCOS2的互斥型信号量的问题请教一下分析了源码的朋友两个问题:1.UCOS2的互斥型信号量的API能不能用于多个
UCOS2的互斥型信号量的问题
请教一下分析了源码的朋友两个问题:
1.UCOS2的互斥型信号量的API能不能用于多个任务中,而不只是两个任务中。或者说互斥锁能不能用于两个任务以上的互斥。
2.如果可以用于多个任务中。那假如说当前有一个任务持有互斥锁,其他任务调用OSMutexPend()时,就会挂起同时会把相关信息加到这个互斥锁对应的挂起队列中。那么持有互斥锁的任务在调用OSMutexPost()的时候,是应该从这个挂起队列里面中抽取优先级最高的置为就绪态,还是把队列中的全部任务全部置为就绪。换个说法就是全部唤醒还是只唤醒优先级最高的那个。
[解决办法]
我们说就绪和优先级,是分开判断的.
所以就绪和优先级也是互相影响的.这里实际涉及到了uc/os-ii的"优先级反转"的概念.
概述下优先级反转原理:
假设有三个任务,分别命名为A,B,C;A的优先级最高,C的优先级最低。任务A和任务B处于挂起状态(请注意这条件),等待某一事件的发生,任务C正在运行。当任务C等待到共享资源(命名为S1)并使用后,如果任务A等待得事件到来之后,由于A的优先级最高,所以就会剥夺任务C的CPU使用权。运行过程中,任务A也要使用资源S1,但S1的信号量还被任务C占用着,所有任务A只能进入挂起状态,等待任务C对S1的信号量的释放。此时任务C得以继续运行。
同理,任务B的事件到来后,会剥夺任务C的CPU使用权。任务B把事情搞定以后,把CPU使用权归还给任务B(呵呵,优先级低就是给人欺负啊,所以做人还真的要争口气!)。任务B又得以继续运行,任务B认真处理完毕资源S1后,终于可以释放S1的信号量。而处于等待该信号量的任务A马上得到信号量并开始处理共享资源S1。
综述上面情况,任务C和任务A的优先级发生了反转。
[解决办法]1.UCOS2的互斥型信号量的API能不能用于多个任务中,而不只是两个任务中。或者说互斥锁能不能用于两个任务以上的互斥。
说说我的理解:
我认为互斥及信号量之类的锁与任务数目没有直接联系、它们针对的对象是资源;它们的存在的目的是为了标识资源状态。
这里的互斥指的是某资源不能同时被多个使用者(相当于多个任务或进程)使用,不要从字面上去理解想当然的以为“互斥”指的是两个进程间的关系。
其实互斥给我的感觉很像是上限为“1”的信号量,要么为“1”,要么为“0”。不知道这相理解对不对……
[解决办法]然后,要解决这个优先级反转的问题,就要用到互斥型信号量,
互斥信号量mutex是二值的,作用是防止优先级反转,可改变占用资源的优先级,实现共享资源的独占
有它自己的函数:
OSMutexCreate()
OSMutexPend()
OSSemPost();
使用它的时候,需要给一个优先级,
纠正上面说得优先级反转的方法可以是,在任务C使用共享资源时,提升任务C的优先级。任务完成时予以恢复。任务C的优先级必须升至最高,高于允许使用该资源的任何任务。
(多任务内核应允许动态改变任务的优先级以避免发生优先级反转现象。然而改变任务的优先级是很花时间的。如果任务C并没有先被任务A剥夺CPU使用权,又被任务B抢走了CPU使用权,花很多时间在共享资源使用前提升任务C的优先级,然后又在资源使用后花时间恢复任务C的优先级,则无形中浪费了很多CPU 时间。)真正需要的是,为防止发生优先级反转,内核能自动变换任务的优先级,这叫做优先级继承(Priority inheritance)。
互斥信号量降解优先级反转的过程:
设mutex已被低优先级的任务3占用。高优先级的任务A提出申请mutex(调用Pend())。在这种情况下:
1)Pend 函数注意到高优先级的任务要用这个共享资源,于是将任务C的优先级升高至Y(创建mutex时指定Y,比任何提出申请mutex的任务的优先级都要高,也就是优先级的值要小),并强制任务调度(由于任务C的优先级升高至9,因此任务C执行),任务C继续使用共享资源。当共享资源使用完后,任务C调用Post函数,释放mutex。
2)Post 函数注意到原来占用这个mutex的任务的优先级是被抬高的,于是将任务C的优先级恢复到原来水平。
3) Post 还注意到有个高优先级的的任务(任务A)正在等待这个mutex,于是将mutex交给这个任务,并做任务切换,让任务A运行。
所以我们看到互斥信号量的组成里面:
$一个标志,指示mutex是否可用(OS_MUTEX_AVAILABLE表示可用)。
$一个优先级,即优先级继承优先级(PIP)。 ---这里有个优先级
$一个等待mutex的任务列表。
因此互斥量可以说是信号量的特殊形式.