From: http://blog.chinaunix.net/uid-23146151-id-3074045.htmlcss
最近在看linux rtmutex部分的实现过程,就像他注释中写的同样,仍是比较简单的。其中比较复杂的部分就是关于任务优先级继承的部分。html
首先介绍优先级反转的背景。node
何为优先级反转?通俗来讲就是低优先级的任务抢占了高优先级的运行权。下面举出一个优先级翻转的场景。linux
系统中有三个具备不一样优先级的任务A,B,C。其中A的优先级最高,B次之,C的优先级最低。系统中A与C共享一个资源,此时C任务先就绪得到此资源的使用权限,这时A任务就绪,也想使用此资源,可是因为C已经在访问状态,因此A被阻塞。此时B任务就绪,若是系统中无优先级翻转处理等机制,那么B任务就会剥夺C任务的运行权限,从而也就剥夺了A任务的运行权限,这样稍低优先级的任务就抢占了高优先级的任务。此种现象就是优先级翻转问题。数据结构
解决优先级翻转的问题一般有几种,一种是优先级继承方式,还有就是天花板方式。函数
二者的区别主要在得到优先级提高的时间,前者在有高优先级任务发生阻塞时,后者是直接在得到资源时提高优先级。ui
再补充一个背景介绍,来自:http://blog.csdn.net/kendiv/article/details/1788966spa
1. 优先级反转(Priority Inversion)
因为多进程共享资源,具备最高优先权的进程被低优先级进程阻塞,反而使具备中优先级的进程先于高优先级的进程执行,致使系统的崩溃。这就是所谓的优先级反转(Priority Inversion)。.net
2. 产生缘由
其实,优先级反转是在高优级(假设为A)的任务要访问一个被低优先级任务(假设为C)占有的资源时,被阻塞.而此时又有优先级高于占有资源的任务(C)而低于被阻塞的任务(A)的优先级的任务(假设为B)时,因而,占有资源的任务就被挂起(占有的资源仍为它占有),由于占有资源的任务优先级很低,因此,它可能一直被另外的任务挂起.而它占有的资源也就一直不能释放,这样,引发任务A一直没办法执行.而比它优先低的任务却能够执行. debug
因此,一个解决办法就是提升占有资源任务的优先级,让它正常执行,而后释放资源,以让任务A能正常获取资源而得以执行.
3. 解决方案 ( 优先级继承 / 优先级天花板 )
目前解决优先级反转有许多种方法。其中广泛使用的有2种方法:一种被称做优先级继承(priority inheritance);另外一种被称做优先级极限(priority ceilings)。
A. 优先级继承(priority inheritance)
优先级继承是指将低优先级任务的优先级提高到等待它所占有的资源的最高优先级任务的优先级.当高优先级任务因为等待资源而被阻塞时,此时资源的拥有者的优先级将会自动被提高.
B. 优先级天花板(priority ceilings)
优先级天花板是指将申请某资源的任务的优先级提高到可能访问该资源的全部任务中最高优先级任务的优先级.(这个优先级称为该资源的优先级天花板)
A 和B的区别:
优先级继承,只有当占有资源的低优先级的任务被阻塞时,才会提升占有资源任务的优先级,而优先级天花板,不管是否发生阻塞,都提高.
-------------------------
rtmutex主要数据结构
rt_mutex,就是一个互斥锁的结构,只有三个元素。
rtmutex waiter的数据结构:用于记录等待互斥锁得结构
主要的数据结构如上所示,后续介绍rtmutex的具体函数调用流程,因为是mutex,那么主要从最大需求的三个方面来介绍,一个是init,一个是lock,最后一个就是unlock
1)初始化函数
此函数已经简单到不能再简单了,将rt_mutex中的相关item初始化。
2)lock函数
其中,rt_mutex_fastlock首先尝试快速得到lock,若是尝试没法成功,则调用rt_mutex_slowlock 继续得到锁。
3)unlock函数
此函数与上述lock函数同样,首先尝试快速的unlock,若是不符合条件,那么再调用rt_mutex_slowunlock函数完成解锁操做。
内部机制,我是很想好好阐述出来的,可是因为本身表达能力有限,等后续总结好了,再更改此篇博客。想写一篇好的技术博客真TM难啊。看懂一个东西简单,讲明白一个东西真TM难,想要理解为啥这么搞更TM难。