转载:Linux kernel rt_mutex的背景和简介
From: http://blog.chinaunix.net/uid-23146151-id-3074045.html
最近在看linux rtmutex部分的实现过程,就像他注释中写的一样,还是比较简单的。其中比较复杂的部分就是关于任务优先级继承的部分。
首先介绍优先级反转的背景。
何为优先级反转?通俗来说就是低优先级的任务抢占了高优先级的运行权。下面举出一个优先级翻转的场景。
系统中有三个具有不同优先级的任务A,B,C。其中A的优先级最高,B次之,C的优先级最低。系统中A与C共享一个资源,此时C任务先就绪获得此资源的使用权限,这时A任务就绪,也想使用此资源,但是由于C已经在访问状态,所以A被阻塞。此时B任务就绪,如果系统中无优先级翻转处理等机制,那么B任务就会剥夺C任务的运行权限,从而也就剥夺了A任务的运行权限,这样稍低优先级的任务就抢占了高优先级的任务。此种现象就是优先级翻转问题。
解决优先级翻转的问题通常有几种,一种是优先级继承方式,还有就是天花板方式。
- 优先级继承方式是指在有任务阻塞到相应共享资源时,所获得资源的任务继承被阻塞任务的优先级,当然只是继承更高的优先级,小于等于的无视。在上例中就为A获得资源被C阻塞时,C任务继承A任务的高优先级,这样B再就绪时就不会抢占C的运行权,从而就避免了优先级翻转现象。
- 优先级天花板办法,就是将获得共享资源时,直接提升任务的优先级到可以获得此种资源的最高优先级。在上例中,当C获得此资源时,直接升到最高的优先级,如果系统中只有A,C使用此资源,那么就升级到A的优先级,这样B就绪时也无法抢占C的运行权,从而避免了优先级反转现象。
两者的区别主要在获得优先级提升的时间,前者在有高优先级任务发生阻塞时,后者是直接在获得资源时提升优先级。
再补充一个背景介绍,来自:http://blog.csdn.net/kendiv/article/details/1788966
1. 优先级反转(Priority Inversion)
由于多进程共享资源,具有最高优先权的进程被低优先级进程阻塞,反而使具有中优先级的进程先于高优先级的进程执行,导致系统的崩溃。这就是所谓的优先级反转(Priority Inversion)。
2. 产生原因
其实,优先级反转是在高优级(假设为A)的任务要访问一个被低优先级任务(假设为C)占有的资源时,被阻塞.而此时又有优先级高于占有资源的任务(C)而低于被阻塞的任务(A)的优先级的任务(假设为B)时,于是,占有资源的任务就被挂起(占有的资源仍为它占有),因为占有资源的任务优先级很低,所以,它可能一直被另外的任务挂起.而它占有的资源也就一直不能释放,这样,引起任务A一直没办法执行.而比它优先低的任务却可以执行.
所以,一个解决办法就是提高占有资源任务的优先级,让它正常执行,然后释放资源,以让任务A能正常获取资源而得以执行.
3. 解决方案 ( 优先级继承 / 优先级天花板 )
目前解决优先级反转有许多种方法。其中普遍使用的有2种方法:一种被称作优先级继承(priority inheritance);另一种被称作优先级极限(priority ceilings)。
A. 优先级继承(priority inheritance)
优先级继承是指将低优先级任务的优先级提升到等待它所占有的资源的最高优先级任务的优先级.当高优先级任务由于等待资源而被阻塞时,此时资源的拥有者的优先级将会自动被提升.
B. 优先级天花板(priority ceilings)
优先级天花板是指将申请某资源的任务的优先级提升到可能访问该资源的所有任务中最高优先级任务的优先级.(这个优先级称为该资源的优先级天花板)
A 和B的区别:
优先级继承,只有当占有资源的低优先级的任务被阻塞时,才会提高占有资源任务的优先级,而优先级天花板,不论是否发生阻塞,都提升.
-------------------------
rtmutex主要数据结构
rt_mutex,就是一个互斥锁的结构,只有三个元素。
- struct rt_mutex {
- raw_spinlock_t wait_lock; /* 保护此结构的自旋锁 */
- struct plist_head wait_list; /* 等待此互斥锁的所有waiter链表 */
- struct task_struct *owner; /* 获得此锁的task,如果没有为NULL */
- }
rtmutex waiter的数据结构:用于记录等待互斥锁得结构
- struct rt_mutex_waiter {
- struct plist_node list_entry; /* 用于将此结构连接到对应的互斥锁上 */
- struct plist_node pi_list_entry; /* 用于将此结构连接到互斥锁所有者上等待链表中 */
- struct task_struct *task; /* 此waiter所属的task,也即等待此mutex的task */
- struct rt_mutex *lock; /* 此waiter等待的mutex */
- };
主要的数据结构如上所示,后续介绍rtmutex的具体函数调用流程,由于是mutex,那么主要从最大需求的三个方面来介绍,一个是init,一个是lock,最后一个就是unlock
1)初始化函数
- void __rt_mutex_init(struct rt_mutex *lock, const char *name)
- {
- lock->owner = NULL;
- raw_spin_lock_init(&lock->wait_lock);
- plist_head_init(&lock->wait_list);
- debug_rt_mutex_init(lock, name);
- }
此函数已经简单到不能再简单了,将rt_mutex中的相关item初始化。
2)lock函数
- void __sched rt_mutex_lock(struct rt_mutex *lock)
- {
- might_sleep();
- rt_mutex_fastlock(lock, TASK_UNINTERRUPTIBLE, 0, rt_mutex_slowlock);
- }
其中,rt_mutex_fastlock首先尝试快速获得lock,如果尝试无法成功,则调用rt_mutex_slowlock 继续获得锁。
3)unlock函数
- void __sched rt_mutex_unlock(struct rt_mutex *lock)
- {
- rt_mutex_fastunlock(lock, rt_mutex_slowunlock);
- }
此函数与上述lock函数一样,首先尝试快速的unlock,如果不符合条件,那么再调用rt_mutex_slowunlock函数完成解锁操作。
内部机制,我是很想好好阐述出来的,但是由于自己表达能力有限,等后续总结好了,再更改此篇博客。想写一篇好的技术博客真TM难啊。看懂一个东西简单,讲明白一个东西真TM难,想要理解为啥这么搞更TM难。
转载:Linux kernel rt_mutex的背景和简介的更多相关文章
- 【嵌入式开发】 Linux Kernel 下载 配置 编译 安装 及 驱动简介
作者 : 韩曙亮 转载请出名出处 : http://blog.csdn.net/shulianghan/article/details/38636827 一. Linux 内核简介 1. 内核功能简介 ...
- Linux Kernel 0.12 启动简介,调试记录(Ubuntu1804, Bochs, gdb)
PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明 本文作为本人csdn blog的主站的备份.(Bl ...
- Android HAL层与Linux Kernel层驱动开发简介
近日稍微对Android中的驱动开发做了一些简要的了解. HAL:Hardware Abstract Layer 硬件抽象层,由于Linux Kernel需要遵循GPL开源协议,硬件厂商为了保护自己硬 ...
- linux kernel 结构体赋值方法{转载}
原文地址: http://www.chineselinuxuniversity.net/articles/48226.shtml 这几天看Linux的内核源码,突然看到init_pid_ns这个结构体 ...
- Linux kernel简介
内核体系设计分:单内核,微内核 windows是微内核设计. Linux是单内核设计,但充分借鉴了为微内核体系的优点,为内核引入了模块化机制. 内核的组成部分 kernel:内核核心,一般为bz压缩的 ...
- 深入linux kernel内核配置选项
============================================================================== 深入linux kernel内核配置选项 ...
- Linux Kernel - Debug Guide (Linux内核调试指南 )
http://blog.csdn.net/blizmax6/article/details/6747601 linux内核调试指南 一些前言 作者前言 知识从哪里来 为什么撰写本文档 为什么需要汇编级 ...
- (十四)Linux kernel mmc 框架说明,包括mmc_test使用方法
1.Linux 总线模型 Linux下的任何驱动在内核中最终都抽象为bus, driver以及device三者间的相互作用. 总线是处理器和一个或多个设备之间的通道,在设备模型中,所有 ...
- linux kernel 杂谈
首先介绍一下背景吧,工作三个星期了.复习了一波u-boot,跟了一下事件上报,搞了下平台设备,扣了一个内存检查代码. 想想生活是不是有点无聊.对啊,真的很无聊!!!! 无聊也没有办法啊,所以找点方法去 ...
随机推荐
- C语言实现二叉树
二叉树的重要性就不用多说啦: 我以前也学习过,但是一直没有总结: 网上找到的例子,要么是理论一大堆,然后是伪代码实现: 要么是复杂的代码,没有什么解释: 最终,还是靠FQ找到一些好的文章,参考地址我会 ...
- atitit.gui界面纵向居中总结
atitit.gui界面纵向居中总结 1.table法...这个简单.. 表格设置100%高度,<td align="center" valign="middle& ...
- JAVA开发工具eclipse中@author怎么改
1:JAVA开发工具eclipse中@author怎么改,开发的时候为了注明版权信息. 用eclipse开发工具默认的是系统用户,那么怎么修改呢 示例如图所示 首先打开Eclipse--->然后 ...
- HTML5骨骼动画Demo | 使用min2d、createjs、pixi播放spine动画
Spine做骨骼动画是比较流行的,使用起来可能相对复杂,但功能毕竟强大,所以市场占有率较大. 在unity.cocos2d.starling中使用spine已经很成熟了,而HTML5这一块可能刚刚起步 ...
- JavaScript 语句 for
循环for语句: for(var i =1;i<=5;i++)(初始条件:循环条件:状态改变) { 循环体 } 循环的作用:反复执行某段代码 四要素:初始条件.循环条件.循环体.状态改变 例题1 ...
- 《Windows核心编程》学习笔记(9)– 在win7或者vista系统下提升一个进程的运行权限
win7或者vista默认运行程序是在受限制的环境下运行的,以减轻病毒对于系统的破坏.那么我们怎样才能提升一个进程的权限以至让它在 管理员模式下运行.当然CreateProcess函数没有提供这个功能 ...
- iphone6 plus 为什么打印出的宽度是375
首先看一张比较简单明了的 iPhone 6 与 iPhone 6 Plus 对比图,来自 PaintCode 的<The Ultimate Guide To iPhone Resolutions ...
- linux下IM server搭建
一步一步开始做. 附录: 一套开源协议:http://www.igniterealtime.org/index.jsp Proso:http://prosody.im/ 那谁网友的笔记http://w ...
- mysql简单性能排查
mysql> show variables; mysql> show processlist; mysql> show status; mysql> show global s ...
- python数据结构之图的实现
python数据结构之图的实现,官方有一篇文章介绍,http://www.python.org/doc/essays/graphs.html 下面简要的介绍下: 比如有这么一张图: A -> B ...