互斥锁
“互斥体(互斥)”指的是任何可以睡眠的强制互斥锁,比如计数是1的信号量。
也就是说,互斥体是一种互斥信号。
互斥在内核中对应数据结构互斥,其行为和使用计数为1的信号量类似,因为是直接调用的信号量的操作接口,实现更高效,而且使用限制更强。也就是一个简化版的信号量,因为不需要管理任何使用计数。
#define MUTEX_DEFAULT 0x0
typedef struct semaphore mutex_t;
#define mutex_init(lock, type, name) sema_init(lock, 1)
#define mutex_destroy(lock) sema_init(lock, -99)
#define mutex_lock(lock, num) down(lock)
#define mutex_trylock(lock) (down_trylock(lock) ? 0 : 1)
#define mutex_unlock(lock) up(lock)
互斥的基本操作列表如下:
互斥锁使用场景
· 任何时刻只有一个任务可以持有互斥,也就是说互斥的使用计数永远是1。
· 在同一上下文中上锁和解锁。切记不能在一个上下文中锁定一个互斥体,而在另一个上下文中给它解锁。这个限制使得互斥体不适合内核同用户空间复杂的同步场景。
· 不能递递地持有同一个锁。也就是不能递上地上锁和解锁,同样也不能去解锁一个已经被解开的互斥。
· 当持有一个互斥时,进程不可以退出。
· 互斥不能在中断或者下半部中使用,即使使用mutex_trylock()也不行。
· 互斥不可被手动初始化,拷贝或者重复初始化。
相比信号量,优先使用使用互斥。如果不能满足其约束条件,且没有其他别的选择时,再考虑选择信号量。
自旋锁和互斥锁
编程中,了解何时使用自旋锁,何时使用互斥锁(或信号量)是很重要的一般情况下,再中断上下文中只能使用自旋锁;而在任务睡眠时只能使用互斥锁。