并发的很多场景中,由于大多数内核临界区,都是在做读访问,写访问很少,如果不区分读写都对临界区上锁,就降低了效率。
为了解决这类访问场景,有了rwsem(读写信号量)。rwsem的临界区有以下几个约束:
rwsem与semaphore一样,只用于进程上下文,等锁进程会进入睡眠。
实现上,rwsem有一个list来维护等待的进程队列,同时在writer持锁时,owner会指向持锁进程。count会保存信号量的值并用高位反应出持锁状态信息。
- /include/linux/rwsem.h
- /kernel/locking/rwsem.c
DECLARE_RWSEM
静态定义初始化
init_rwsem
动态初始化
down_read
获取信号量(-1),如果write lock,则睡眠
down_read_interruptible
同上,如果睡眠过程中被signal唤醒,则返回-EINTR,正常等到up唤醒返回0
down_read_killable
同上,不允许普通signal唤醒,如果睡眠过程中被faltal signal唤醒,则返回-EINTR,正常等到up唤醒返回0
down_read_trylock
获取成功返回0,没申请到不睡眠,直接返回1
down_write
获取信号量(-1),如果有read / write lock,则睡眠
down_write_killable
同上,不允许普通signal唤醒,如果睡眠过程中被faltal signal唤醒,则返回-EINTR,正常等到up唤醒返回0
down_write_trylock
获取成功返回0,没申请到不睡眠,直接返回1
up_read
up_write
释放信号量(+1),并唤醒信号量等待进程队列中的第一个进程。
https://0xax.gitbooks.io/linux-insides/content/SyncPrim/linux-sync-5.html