Linux内核同步方法——读写锁

读 - 写自旋锁

    一个或多个任务可以并发地持有读者锁;相反,用于写的锁最多只能被一个写任务持有,而且此时不能有并发地读操作。

   读/写锁也叫做共享/排斥锁,或者并发/排斥锁,因为这种锁对读者而言是共享地,对写者以排斥形式获取地。


基本数据结构

    在内核代码中,读-写自旋锁用rwlock_t类型表示,

typedef struct {
	/**
	 * 这个锁标志与自旋锁不一样,自旋锁的lock标志只能取0和1两种值。
	 * 读写自旋锁的lock分两部分:
	 *     0-23位:表示并发读的数量。数据以补码的形式存放。
	 *     24位:未锁标志。如果没有读或写时设置该,否则清0
	 * 注意:如果自旋锁为空(设置了未锁标志并且无读者),则lock字段为0x01000000
	 *     如果写者获得了锁,则lock为0x00000000(未锁标志清0,表示已经锁,但是无读者)
	 *     如果一个或者多个进程获得了读锁,那么lock的值为0x00ffffff,0x00fffffe等(未锁标志清0,后面跟读者数量的补码)
	 */
	volatile unsigned int lock;
#ifdef CONFIG_DEBUG_SPINLOCK
	unsigned magic;
#endif
#ifdef CONFIG_PREEMPT
	/**
	 * 表示进程正在忙等待自旋锁。
	 * 只有内核支持SMP和内核抢占时才使用本标志。
	 */
	unsigned int break_lock;
#endif
} rwlock_t;

rwlock_t中的锁标志与自旋锁不同,

    (注:如果自旋锁为空(设置了未锁标志并且无读者),则锁字节位0x0100 0000)(自锁锁的锁标志只能取0和1两种值。

读写自旋锁的锁分为两部分:

    · 0-23位:表示并发读的数量;

    ·第24位:未锁标志如果没有读或写时会设置,否则清0。

如果写者获得了锁,则锁为0x0000 0000(未锁标志清0,表示已经锁,但无读者);如果一个或多个进程获得了读锁,那么锁的值为0x00ff ffff,0x00ff fffe锁标志清0)。



初始化

    rwlock_init(),初始化指定的rwlock_t。

#define rwlock_init(x)	do { *(x) = RW_LOCK_UNLOCKED; } while(0)

read_lock

    获得指定的读锁。

    在没有配置内核抢占时,read_lock的实现如下,

/**
 * 在没有配置内核抢占时,read_lock的实现。
 */
void __lockfunc _read_lock(rwlock_t *lock)
{
	preempt_disable();
	_raw_read_lock(lock);
}
EXPORT_SYMBOL(_read_lock);

    接下来,read_lock调用_raw_read_lock(),其中第一个参数为读写锁指针,第二个为获取读锁失败时的处理函数的函数指针。

/**
 * 在没有配置内核抢占时,read_lock调用它。
 */
static inline void _raw_read_lock(rwlock_t *rw)
{
#ifdef CONFIG_DEBUG_SPINLOCK
	BUG_ON(rw->magic != RWLOCK_MAGIC);
#endif
	__build_read_lock(rw, "__read_lock_failed");
}

__build_read_lock

    函数raw_read_lock调用宏函数__build_read_lock,

这里的__builtin_constant_p()是编译器的GCC的内置函数,用于判断一个值是否为编译时常量,如果是,函数返回1,否则返回0。

#define __build_read_lock(rw, helper)	do { \
						if (__builtin_constant_p(rw)) \
							__build_read_lock_const(rw, helper); \
						else \
							__build_read_lock_ptr(rw, helper); \
					} while (0)

__build_read_lock_ptr和__build_read_lock_const

    在没有内核抢占时,助手为__read_lock_failed。

/**
 * 在没有内核抢占时,read_lock会调到这里来。
 * 在那种情况下,helper为__read_loc
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值