莫小帅|Linux kernel同步机制(上篇)( 四 )
当unlock时 , 不考虑等待队列的影响 , 则与上述类似 , 当且仅当之前持有锁的owner可以解锁 , 解锁时本来应将lock的owner置为初始0 , 但是这里保留了mutex的flag以便后续操作 。
*这里的owner实际上是task_struct的指针 , 也就是地址 , 由于task_struct的地址是L1_cache对齐的 , 因此实际上指针地址后三位为0 , 因此linux内核利用这三个比特位用于设置mutex的标志位 , 不影响指针地址的表示也更高效利用了冗余的比特位 。
Mutex 的改进
最初的互斥锁仅支持睡眠等待 , 然而经过漫长时间的改进 , 如今的互斥锁已经可以支持自旋等待 , 通过MCS锁机制实现 。 在内核中可以选择配置以支持 , CONFIG_MUTEX_SPIN_ON_OWNER 。
如上是4.9内核中mutex中常用有效的字段 , 目前最常用的算法是OSQ算法 。 自旋等待机制的核心原理是当发现持有者正在临界区执行并且没有其他优先级高的进程要被调度(need_resched)时 , 那么mutex当前所在进程认为该持有者很快会离开临界区并释放锁 , 此时mutex选择自旋等待 , 短时间的自旋等待显然比睡眠-唤醒开销小一些 。
在实现上MCS保证了同一时间只有一个进程自旋等待持有者释放锁 。 MCS 的实现较为复杂 , 具体可参考一些内核书籍 。 MCS保证了不会存在多个cpu争用锁的情况 , 从而避免了多个CPU的cacheline颠簸从而降低系统性能的问题 。
经过改进后 , mutex的性能有了相当大的提高 , 相对信号量的实现要高效得多 。 因此我们尽量选用mutex 。
Mutex 的使用条件
Mutex虽然高效 , 灵活 , 但存在若干限制条件 , 需要牢记:
- 同一时刻只有一条内核路径可以持有锁
- 只有锁持有者可以解锁
- 不允许递归加锁解锁
- 进程持有mutex时不可退出
- Mutex 可能导致睡眠阻塞 , 不可用于中断处理与下半部使用
未完待续...
推荐阅读
- 莫小帅|极乐音乐app下载(软件篇)
- 莫小帅|不仅配置颜值很高,性价比也不错,目前最值得购买的三款华为手机
- 精英联盟总队|最详细的Linux简史——Linux大神带你领略它的前世今生
- 莫小帅|目前最值得购买的三款华为手机,不仅配置颜值很高,性价比也不错
- 莫小帅|14块8包邮廉价游戏耳麦晒单:RGB、蛋白耳罩、双钢梁全配齐
- 轻拔琴弦|给你一个反悔的机会
- 莫小帅|手机这么玩,以后谁还戴套
- 莫小帅|8月“最流畅”安卓手机榜,小米问鼎第一,三星竟然才第七?
- 莫小帅|英特尔 11 代酷睿发布:等,还是 AMD,Yes?
- 莫小帅|9月第一周
