RTEMS同步互斥与优先级处理算法
对于各个task线程之间需要同步互斥的情况,RTEMS提供信号量(semaphore)、自旋锁(SpinLock)、读写锁(RWLock)等互斥机制。
信号量:
RTEMS支持二值信号量和计数信号量。二值信号量只能取0和1两个值,当值为0时,表示信号量不可用,当值为1,表示可以使用。而计数信号量的取值可以是任何非负的整数,当值大于0时,表示信号量可以使用。二值信号量用于控制单个资源的互斥访问,而计数信号量控制资源集的访问,例如有三个打印机,这样就不能简单的把信号量设置为0或1,而应该采用计数信号量,设置为3.
也可通过信号量来实现task之间的同步,比如设置信号量的初值为0,运行A到同步点,调用信号量获取操作,A发现信号量为0,继续等待,B到达同步点后,调用信号量释放操作,A设置为1。这样就同步了。
RTMES的核心层提供了semaphore handler组件和mutex handler组件,实现了核心信号量和核心互斥体两种核心机制。
信号量的嵌套访问:
当已经占有一个互斥信号量的任务企图获得同一个互斥信号量时,可能发生死锁,如下图所示:
信号量Sa分配给了Ta,且没有释放,Ta又在等待Tb释放互斥信号量Sb,同时Tb在等待Ta释放Sa,发生死锁。
在编程时,比如A,B两个函数都需要获得某一共享对象,如果函数A在获得了共享对象后调用B,这时候就发生了竞争。RTEMS运行任务嵌套获取资源来解决这种问题,在持有信号量时可以获得同一信号量,但获取和释放必须配对。
优先级反转
在实时操作系统中,高优先级任务需要访问的资源被低优先级任务占用,导致高优先级任务阻塞,高优先级任务必须等待低优先级任务释放资源后才能唤醒。若低优先级任务还被其他优先级中等的任务抢占了CPU,那么优先级反转现象进一步恶化。
RTMES采用优先级继承算法和优先级天花板算法两种机制解决优先级反转问题
优先级继承算法:
优先级继承算法是一种动态提高获得互斥共享资源的任务的优先级的算法,如果该任务由低优先级变为高优先级,那么中等优先级的任务就不会抢占该任务。算法如下图所示:
如上图所示,A首先获得信号量,并且对信号量加锁,当B在获取同一信号量时,通过_CORE_mutex_Seize_interrupt_trylock发现低优先级的A占有信号量,那么操作系统将A的优先级提高到与B相同,这样B阻塞,A继续执行直到A完成对资源的操作,将信号量释放,同时A降为原来的优先级。此时B占有信号量,会剥夺A对处理器的占用,然后运行。
当然也考虑到实时任务拥有多个资源的信号量这一情况,此时占据资源的任务的优先级将会改变,新的优先级是所有阻塞任务的优先级的最小值(值越小,优先级越高)。只有当任务释放所有的信号量,优先级才会回到原始水平。
优先级天花板算法
优先级天花板算法中,每个任务的优先级是已知的,每个任务要求的资源在执行前也是已知的。资源具有优先级,其优先级与预计要求占用此资源的任务中的最高优先级相同,要求占用资源的任务的优先级在得到资源后,会动态提升任务自身的优先级,新的优先级是任务此时所占用的所有资源中的最高的资源优先级。该算法通过一次性改变任务优先级的方式解决任务优先级反转问题。
如上图所示,信号量在初始化时候扫描所有对自己感兴趣的task,然后将自己的优先级设置为这些任务的优先级的天花板值-100,这样任务A在获取信号量成功后将自己的优先级也变为100,直到A结束,优先级不会变化。
在大型实时应用系统中获取优先级天花板的操作会很复杂,由于优先级天花板算法只用改变一次任务的优先级,所以比优先级基继承算法更为高效。但是当系统复杂,扫描这些task也会降低执行效率。所以很多情况下,需要设计者手工设定ceiling值。
需要注意的是:优先级继承算法不能防止死锁,但优先级天花板算法可以。
posted on 2018-01-24 22:33 sichenzhao 阅读(462) 评论(0) 编辑 收藏 举报