持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第12天,点击查看活动详情
前言
📫作者简介:小明java问道之路,专注于研究 Java/ Liunx内核/ C++及汇编/计算机底层原理/源码,就职于大型金融公司后端高级工程师,擅长交易领域的高安全/可用/并发/性能的架构设计与演进、系统优化与稳定性建设。
📫热衷分享,喜欢原创~ 关注我会给你带来一些不一样的认知和成长。
🏆InfoQ签约作者、CSDN专家博主/后端领域优质创作者/内容合伙人、阿里云专家/签约博主、51CTO专家🏆
🔥如果此文还不错的话,还请👍关注 、点赞 、收藏三连支持👍一下博主~
本文导读
Linux内核读锁实现原理,描述自旋锁时,已经顺带描述了读写自旋锁,所以本节将不再描述自旋锁的读写锁实现。读者是否能想到,既然自旋锁有相关的读写锁实现,信号量也应该有呢?答案是一定的。所以可以到,读写锁实际上是在原有锁上进行优化读写的操作。下面讨论源码实现。
一、Linux内核读写锁核心结构源码解读
定义一个结构体rw_semaphore代表读写信号量,然后义一宏定义表明读写信号量的偏移值。具体源码如下。
struct rw_semaphore{
// 符号长整型,看到long类型,读者就知道,这又是将一个long类型长度大小切割成不同部分来使用的
// 由于使用i38632位来作为例子,因此这里long为32位,同样我们分割为高16位和低16位来使用
signed long count;
#define RWSEM UNLOCKED VALUE 0x0000 0000 // 无锁状态值为0
#define RWSEM_ACTIVE_BIAS 0x0000 0001 // 锁活动偏移值1
// 锁活动位数为4(4个16进制)*4(一个16进制等于4个二进制)=16,即2^16次方个锁位
#define RWSEM ACTIVE MASK Ox0000 ffff
#define RWSEM_WAITING BIAS (-0x00010000) // 锁等待偏移量,即 0xffff 0000
#define RWSEM ACTIVE READ_BIAS RWSEM_ACTIVE_BIAS // 读锁偏移量
// 写锁偏移量0xffff0001 为负数
#define RWSEM ACTIVE WRITE BIAS (RWSEM_WAITING_BIAS+RWSEM_ACTIVE_BIAS)
spinlock t wait_lock; // 保护等待链表的自旋锁
struct list_head wait_list; // 等待链表
};
//等待读写信号量的任务结构体
struct rwsem_waiter{
struct list_head list;
struct task_struct *task;
unsigned int flags; // 标志位声明为等待读锁还是写锁
#define RWSEM_WAITING_FOR_READ 0x00000001
#define RWSEM_WAITING_FOR_WRITE 0x00000002
};