ILD

Kernel Synchronization 3: Semaphores & Mutexes
作者:YUAN JIANPENG 邮箱:yuanjp@hust.edu.cn
发布时间:2018-8-20 站点:Inside Linux Development

Semaphores

linux中的信号量是sleeping lock。当尝试获得的锁当前被占用时,它把task放入一个等待队列,然后把task置于睡眠状态。当信号量变成可用时,唤醒task,并获得信号量。



信号量不会禁用抢占。


Counting and binary semaphores

信号量同时允许的持有者数量在声明信号量时指定,这个值被称为使用者数量或者简称为数量。


通常情况下,只允许一个锁持有者,count等于1,这种信号量叫做binary semaphore,或者叫做mutex。


大于1,叫做counting semaphores。但是这种在内核中不常用。


信号量支持两个原子操作:P() 和 V(),后面的系统叫做 down() 和 up()。down() 用来获得信号量,通过给计数减1。up() 用来释放信号量。


Creating and Initializing Semaphores

信号量的实现和架构相关,头文件 <asm/semaphore.h>,类型:struct semaphore。


定义并初始化

1
2
struct semaphore name;
sema_init(&name, count);


定义并初始化一个binary semaphore

1
static DECLARE_MUTEX(name);


初始化一个动态创建的mutex,可以使用

1
init_MUTEX(sem);


Using semaphores

down_interruptible() 尝试获得信号量,如果信号量不可用,它将进程睡眠到TASK_INTERRUPTIBLE状态。当信号发生时,函数返回-EINTR。

down() 则睡眠成不可中断状态。


典型的用法

1
2
3
4
5
6
7
8
9
10
11
/* define and declare a semaphore, named mr_sem, with a count of one */
static DECLARE_MUTEX(mr_sem);
 
/* attempt to acquire the semaphore ... */
if (down_interruptible(&mr_sem)) {
    /* signal received, semaphore not acquired ... */
}
/* critical region ... */
 
/* release the given semaphore */
up(&mr_sem);


Semaphore Methods

MethodDesc
sema_init(struct semaphore *, int)
init_MUTEX(struct semaphore *)
init_MUTEX_LOCKED(struct semaphore *)
down_interruptible (struct semaphore *)
down(struct semaphore *)
down_trylock(struct semaphore *)
up(struct semaphore *)


Reader-Writer Semaphores

类型 struct rw_semaphore,头文件<linux/rwsem.h>


定义并初始化

1
static DECLARE_RWSEM(name);


动态初始化

1
init_rwsem(struct rw_semaphore *sem)


所有的读写信号量都是mutex。count为1。使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
static DECLARE_RWSEM(mr_rwsem);
 
/* attempt to acquire the semaphore for reading ... */
down_read(&mr_rwsem);
 
/* critical region (read only) ... */
 
/* release the semaphore */
up_read(&mr_rwsem);
 
/* attempt to acquire the semaphore for writing ... */
down_write(&mr_rwsem);
 
/* critical region (read and write) ... */
 
/* release the semaphore */
up_write(&mr_sem);


还有down_read_trylock()和down_write_try_lock()。读写信号量还支持将写锁变成一个读锁:downgrade_write()


Mutexes

结构struct mutex,它和计数为1的信号量类似,但是接口更简单,效率更高,但有一些额外的约束。


静态声明

1
DEFINE_MUTEX(name);


动态初始化

1
mutex_init(&mutex);


上锁和解锁

1
2
3
mutex_lock(&mutex);
/* critical region ... */
mutex_unlock(&mutex);


Mutex Methods

mutex_lock(struct mutex *)
mutex_unlock(struct mutex *)
mutex_trylock(struct mutex *)
mutex_is_locked (struct mutex *)


互斥体有一些约束


Copyright © linuxdev.cc 2017-2024. Some Rights Reserved.