顺序锁的应用

自旋锁不允许读和读之间的并发,读写锁则更进了一步,允许读和读之间的并发,顺序锁又更进了一步,允许读和写之间的并发。为了实现这一需求,顺序锁在读时不上锁,也就意味着在读的期间允许写,但是在读之前需要先读取一个顺序值,读操作完成之后,再次读取顺序值,如果两者相等,说明在读的过程中没有发生写操作,否则要重新读取。显然,写操作要上锁,并且要更新顺序值。顺序锁特别适合读很多而写很少的场合,否则由于反复的读操作,也不一定能获得较高的效率。顺序锁的数据类型是seqlock_t,其类型定义如下:

typedef struct{
	struct seqcount seqcount;
	spinlock_t lock;
}seqlock_t;

很显然,顺序锁使用了自旋锁的机制,并且有一个顺序值seqcount,顺序锁的主要API如下:

seqlock_init(x)
unsigned read_seqbegin(const seqlock_t *sl);
unsigned read_seqretry(const seqlock_t *sl,unsigned start);
void write_seqlock(seqlock_t *sl);
void write_sequnlock(seqlock_t *sl);
void write_seqlock_bh(seqlock_t *sl);
void write_sequnlock_bh(seqlock_t *sl);
void write_seqlock_irq(seqlock_t *sl);
void write_sequnlock_irq(seqlock_t *sl);
write_seqlock_irqsave(lock,flags);
void write_sequnlock_irqrestore(seqlock_t *sl,unsigned long flags);

seqlock_t init:初始化顺序锁。
read_seqbegin:读之前获取顺序值,函数返回顺序值。
read_seqretry:读之后验证顺序值是否发生了变化,返回1表示需要重读,返回0表示读成功。
write_seqlock:写之前加锁,其他的变体参照自旋锁。
write_sequnlock:写之后解锁,其他的变体参照自旋锁。
我们可以使用下面的代码来使顺序锁对 i 的操作进行互斥:

int i = 5;
unsigned long flags;
/*定义顺序锁*/
seqlock_t lock;
/*使用之前必须初始化顺序锁*/
seqlock_init(&lock);

int v;
unsigned start;
do{
	/*读之前要获取顺序值*/
	start = read_seqbegin(&lock);
	v = i;
/*读完之后检查顺序自是否发生了变化,如果是,则要重读*/
}while(read_seqretry(&lock,start));

/*写之前获取顺序锁*/
write_seqlock_irqsave(&lock,flags);
i++;
/*写完之后释放顺序锁*/
write_sequnlock_irqrestore(&lock,flags);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值