Linux内核同步机制-互斥锁
2021-03-17 本文已影响0人
小田BSP
一、初始化
互斥锁(mutex
)定义文件:include/linux/mutex.h
,方法如下:
1、静态定义并初始化
#define DEFINE_MUTEX(mutexname) \
struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
2、动态初始化
# define mutex_init(mutex) \
do { \
static struct lock_class_key __key; \
\
__mutex_init((mutex), #mutex, &__key); \
} while (0)
在使用互斥锁时,上面定义可任选其一。
3、结构体mutex
定义
/*
* Simple, straightforward mutexes with strict semantics:
*
* - only one task can hold the mutex at a time
* - only the owner can unlock the mutex
* - multiple unlocks are not permitted
* - recursive locking is not permitted
* - a mutex object must be initialized via the API
* - a mutex object must not be initialized via memset or copying
* - task may not exit with mutex held
* - memory areas where held locks reside must not be freed
* - held mutexes must not be reinitialized
* - mutexes may not be used in hardware or software interrupt
* contexts such as tasklets and timers
*
*/
struct mutex {
/* 1: unlocked, 0: locked, negative: locked, possible waiters */
atomic_t count; ## 1:没有上锁,可以使用;0:已锁定;负数:已锁定,可能还有任务等待该锁
spinlock_t wait_lock;
struct list_head wait_list; ## 等待互斥锁的任务队列
...
};
说明:
1)同一时刻只有一个任务持有互斥锁
2)只有互斥锁的持有者才可以释放
3)不允许多次释放互斥锁
4)不允许递归获取互斥锁
5)必须通过互斥锁的API函数初始化
6)不能使用memset
初始化互斥锁
7)持有互斥锁的任务不能退出
8)互斥锁所在内存不能被释放
9)被持有的互斥锁不能被再次初始化
10)互斥锁不能在硬件中断或软中断上下文中使用,例:tasklets and timers
。
二、使用
定义文件:kernel/locking/mutex.c
。
1.获取互斥锁
void __sched mutex_lock(struct mutex *lock);
说明:获取互斥锁,成功则返回;否则,当前进程进入睡眠状态,等待下次调度,重新获取互斥锁。
int __sched mutex_trylock(struct mutex *lock)
说明:获取互斥锁,不论是否成功,直接返回,不等待。
int __sched mutex_lock_interruptible(struct mutex *lock)
说明:功能类似mutex_lock
。成功获取互斥锁,返回0;如果在等待获取锁时,被信号中断睡眠状态,则返回-EINTR。
2.释放互斥锁
void __sched mutex_unlock(struct mutex *lock);
三、举例
## 1、初始化
static DEFINE_MUTEX(mutex_a);
struct mutex mutex_b;
## 2、使用
void fn1(void)
{
...
mutex_lock(&mutex_a);
... ## 临界资源处理
mutex_unlock(&mutex_a);
}
void fn2(void)
{
...
mutex_lock(&mutex_b);
... ## 临界资源处理
mutex_unlock(&mutex_b);
}