【精通内核】Linux内核读写锁核心结构源码解读

267 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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
};