莫小帅|kernel同步机制(上篇),Linux( 四 )


*这里的owner实际上是task_struct的指针 , 也就是地址 , 由于task_struct的地址是L1_cache对齐的 , 因此实际上指针地址后三位为0 , 因此linux内核利用这三个比特位用于设置mutex的标志位 , 不影响指针地址的表示也更高效利用了冗余的比特位 。
Mutex的改进
最初的互斥锁仅支持睡眠等待 , 然而经过漫长时间的改进 , 如今的互斥锁已经可以支持自旋等待 , 通过MCS锁机制实现 。 在内核中可以选择配置以支持 , CONFIG_MUTEX_SPIN_ON_OWNER 。
在实现上MCS保证了同一时间只有一个进程自旋等待持有者释放锁 。 MCS的实现较为复杂 , 具体可参考一些内核书籍 。 MCS保证了不会存在多个cpu争用锁的情况 , 从而避免了多个CPU的cacheline颠簸从而降低系统性能的问题 。
经过改进后 , mutex的性能有了相当大的提高 , 相对信号量的实现要高效得多 。 因此我们尽量选用mutex 。
Mutex的使用条件
Mutex虽然高效 , 灵活 , 但存在若干限制条件 , 需要牢记:
同一时刻只有一条内核路径可以持有锁只有锁持有者可以解锁不允许递归加锁解锁进程持有mutex时不可退出Mutex可能导致睡眠阻塞 , 不可用于中断处理与下半部使用MutexAPI