什么是互斥锁?Linux内核中互斥锁的定义、优点及实现方式
什么是互斥锁?
在Linux内核中,互斥锁指的是在共享内存系统上强制序列化的特定锁定原语,而不仅仅是指学术界或类似理论教科书中提到的“互斥”的通用术语。
互斥锁是一种休眠锁,其行为类似于二进制信号量,2006年引入互斥锁作为它们的替代。这种新的数据结构提供了许多优点,包括更简单的接口,以及当时更小的代码(见缺点)。
实现
互斥量由“ mutex”表示,在/linux/mutex.h中定义,并在//mutex.c中实现。这些锁使用一个原子变量(->owner)来跟踪锁在其生命周期中的状态。“owner” 字段实际上包含当前锁所有者的 “ *” ,因此如果当前不属于它,则为 NULL 。由于任务结构指针至少对齐一级缓存字节(),因此使用低位(3)存储额外的状态(例如,如果等待列表为非空)。它最基本的形式还包括一个等待队列和一个对其进行序列化访问的自旋锁。此外,如果配置 =y ,那么系统使用一个 MCS lock (->osq), 将在下面的 (2) 中进行描述。
获取互斥锁时,根据锁的状态,可以采用三种可能的路径:
: 尝试通过()对当前任务的所有者原子地获取锁。这只适用于无竞争的情况(()检查0UL,因此上面的3个状态位都必须为0)。如果锁被争夺,它将转到下一个可能的路径。
: 又名乐观旋转(aka ),尝试在锁所有者运行时旋转获取,并且没有其他准备运行的任务具有更高的优先级()。理由是,如果锁所有者正在运行,则很可能会很快释放锁。 互斥锁微调器(Mutex )使用MCS锁定排队,因此只有一个微调器可以竞争该互斥锁。
MCS锁(由-和Scott提出)是一种简单的自旋锁,具有理想的公平属性,并且每个cpu都试图获取在局部变量上旋转的锁。它避免了常见的测试和设置自旋锁实现招致的昂贵的高速缓存行反弹。类似于MCS的锁是专门为乐观旋转而量身定制的,用于实现睡眠锁。自定义MCS锁的一个重要功能是,它具有额外的属性,使微调程序可以在需要重新计划时退出MCS自旋锁队列。这进一步有助于避免需要重新安排时间的MCS微调器继续等待旋转互斥体所有者,而仅在获得MCS锁定后直接进入慢速路径的情况。
: 不得已时,如果仍然无法获取锁定,则将任务添加到等待队列中并休眠直到被解锁路径唤醒。 通常情况下,它以 的形式阻塞。
虽然形式上的内核互斥锁是可睡眠的锁,但路径(2)使它们实际上更是一种混合类型。 通过简单地不中断任务并忙于等待几个周期而不是立即休眠,该锁的性能可以显着改善许多工作负载。 请注意,此技术还用于rw信号量。
互斥锁子系统检查并执行以下规则:
启用 时,将完全强制执行这些语义。 此外,互斥锁调试代码还实现了许多其他功能,这些功能使锁调试更容易,更快捷:
静态定义互斥锁:
动态初始化互斥锁:
获取互斥锁,:
获取互斥锁,:

the mutex, , if dec to 0:
解锁互斥锁:
测试互斥锁是否被其他任务锁定:
its and , ‘ mutex’ is among the locks in the . E.g: on x86-64 it is 32 bytes, where ‘ ’ is 24 bytes and is 40 bytes. sizes mean more CPU cache and .
When to use
the of are and/or the the lock from being , them to any other .
简单来说就是不在中断里面用,在哪用都是比较优的选择。
参考
























