09、读写锁(rwlock)
一、读写锁
读写锁能提升程序的运行效率。它的规则很简单:
- 多个线程可以同时读取共享数据(比如同时查看文件内容),但一旦有线程要修改数据(比如编辑文件),所有其他线程都必须等待;
- 只允许一个线程在写入数据(比如同时只能有一个人在编辑文件);
- 当有线程在读取或写入时,其他想写入的线程必须排队等待,不能同时进行。
这样既保证了数据安全,又能充分利用资源——比如多个用户同时查看网页时不会互相影响,但编辑网页内容时需要独占操作权限。
二、API
读写锁主要分为两种类型:
- 读者自旋锁和读者信号量是两种不同的读写锁机制,用于协调对共享资源的读写操作。
- 它们的具体实现细节(数据结构)被写在 Linux 内核的头文件
include/linux/rwlock_types.h
中。
C
<include/linux/rwlock_types.h>
typedef struct {
arch_rwlock_t raw_lock;
} rwlock_t;
<include/asm-generic/qrwlock_types.h>
typedef struct qrwlock {
union {
atomic_t cnts; //原子
struct {
u8 wlocked;
u8 __lstate[3];
};
};
arch_spinlock_t wait_lock;
} arch_rwlock_t;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
读写锁常用函数说明:
- rwlock_init():初始化读写锁
- write_lock():申请独占写锁
- write_unlock():释放写锁
- read_lock():申请共享读锁
- read_unlock():释放读锁
- read_lock_irq():关闭中断后申请读锁
- write_lock_irq():关闭中断后申请写锁
- write_unlock_irq():释放写锁并恢复中断
三、内核中使用案例
net/nfc/af_nfc.c
读取:
写入:
总结:
- nfc_sock_create :可以被调用多次,并且可以梳理执行
- nfc_proto_register:前提nfc_sock_create 先读完,nfc_proto_register才会执行
- nfc_proto_register 没有执行完之前,谁(nfc_proto_register 、nfc_sock_create )都无法再次执行。