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);
}
上一篇下一篇

猜你喜欢

热点阅读