当前位置: 首页 > news >正文

bootstrap 网站案例学seo优化

bootstrap 网站案例,学seo优化,做维修电器网站,wordpress同步微信Linux 内核有非常多的锁机制,如:自旋锁、读写锁、信号量和 RCU 锁等。本文介绍一种和读写锁比较相似的锁机制:顺序锁(seqlock)。 顺序锁与读写锁一样,都是针对多读少写且快速处理的锁机制。而顺序锁和读写…

Linux 内核有非常多的锁机制,如:自旋锁、读写锁、信号量和 RCU 锁等。本文介绍一种和读写锁比较相似的锁机制:顺序锁(seqlock)。

顺序锁与读写锁一样,都是针对多读少写且快速处理的锁机制。而顺序锁和读写锁的区别就在于:读写锁的读锁会阻塞写锁,而顺序锁的读锁不会阻塞写锁。

读锁原理

为了让读锁不阻塞写锁,读锁并不会真正进行上锁操作。那么读锁是如何避免在读取临界区数据时,数据被其他进程修改了?

为了解决这个问题,顺序锁使用了一种类似于版本号的机制:序号。序号是一个只增不减的计数器,可以从顺序锁对象的定义看出,如下代码所示:

typedef struct {struct seqcount seqcount; // 序号spinlock_t lock;          // 自旋锁,写锁上锁时使用
} seqlock_t;

在读取临界区数据前,首先需要调用 read_seqbegin() 函数来获取读锁,read_seqbegin() 函数的核心逻辑是读取顺序锁的序号。代码如下所示:

static inline unsigned read_seqbegin(const seqlock_t *sl)
{unsigned ret;repeat:// 读取顺序锁的序号ret = sl->sequence;// 如果序号是单数,需要重新获取if (unlikely(ret & 1)) {...goto repeat;}...return ret;
}

从上面的代码可以看出,read_seqbegin() 函数只获取顺序锁的序号,并不会进行上锁操作,所以读锁并不会阻塞写锁。

注意:序号是单数时需要重新获取的原因,会在分析写锁实现原理时说明。

既然读锁并不会进行上锁操作,如果在读取临界区数据时,数据被修改了怎么办呢?答案就是:在退出临界区时,比较一下当前顺序锁的序号跟之前读取的序号是否一致。如果一致表示数据没有被修改,否则说明数据已经被修改。如果数据被修改了,那么需要重新读取临界区的数据。

比较序号是否一致可以使用 read_seqretry() 函数,所以读锁的正确用法如下代码所示:

do {// 获取顺序锁序号unsigned seq = read_seqbegin(&seqlock);// 读取临界区数据...
} while (read_seqretry(&seqlock, seq)); // 对比序号是否一致?

read_seqretry() 函数的实现非常简单,如下所示:

static inline unsigned 
read_seqretry(const seqlock_t *sl, unsigned start)
{...return sl->sequence != start;
}

从上面代码可以看出,read_seqretry() 函数只是简单比较当前序号与之前读取到的序号是否一致。

写锁原理

从上面的分析可知,读锁是通过对比前后序号是否一致来判断数据是否被修改的。那么序号在什么时候被修改呢?答案就是:获取写锁时。

获取写锁是通过 write_seqlock() 函数来实现的,其实现也比较简单,代码如下所示:

static inline void write_seqlock(seqlock_t *sl)
{spin_lock(&sl->lock);sl->sequence++;...
}

write_seqlock() 函数首先会获取自旋锁(所以写锁与写锁之间是互斥的),然后对序号进行加一操作。所以,在修改临界区数据前,写锁先会增加序号的值,这样就会导致读锁前后两次获取的序号不一致。我们可以用下图来说明这种情况:

seqlock原理

 资料直通车:Linux内核源码技术学习路线+视频教程内核源码

学习直通车:Linux内核源码内存调优文件系统进程管理设备驱动/网络协议栈

可以看出,当在读临界区前后获取的序号值不一致时,就表示数据已经被修改,这时就需要重新读取被修改后的数据。

写锁解锁也很简单,代码如下:

static inline void write_sequnlock(seqlock_t *sl)
{...s->sequence++;spin_unlock(&sl->lock);
}

解锁也需要对序号进行加一操作,然后释放自旋锁。

由于 write_seqlock() 函数与 write_sequnlock() 函数都会对序号进行加一操作,所以解锁后,序号的值必定为双数。

我们在分析读锁时看到,如果序号是单数时会重新获取序号,直到序号为双数为止。这是因为序号单数时,表示正在更新数据。此时读取临界区的值是没有意义的,所以需要等到更新完毕再读取。

原文作者:Linux内核那些事

http://www.khdw.cn/news/24936.html

相关文章:

  • 十堰网站建设有哪些公司收录提交入口网址
  • 有没有什么网站专门帮人做问卷外国网站怎么进入
  • 网站建设与运营厦门seo新站策划
  • 地方网站用什么域名如何做好关键词的优化
  • ps做网站教程网站下载免费软件
  • 中国建筑英才网重庆seo团队
  • 可视化网站建设软件上海营销公司
  • 企业网站建设与实施调查报告免费b站推广网站链接
  • 大数据营销工具在线刷seo
  • 网站怎么加链接北京网站seo
  • 服装网站建设配色免费论坛建站系统
  • 两学一做知识竞答网站搜索引擎营销特点
  • wordpress移动适配上海网络seo优化公司
  • 网站上的定位功能如何实现的北京搜索引擎优化管理专员
  • 公司官网怎么注册流程搜索引擎优化管理实验报告
  • 中山网站建设包括哪些20条优化措施
  • 牡丹江市建设局网站优化是什么梗
  • 手机网站建站公司有哪些最热门的短期培训课程
  • 用外链css做网站去哪里找需要推广的app
  • 网站添加邮件发送怎么做cnzz
  • 买个网站服务器多少钱下载百度
  • 琪恋网站建设怎么做公司网站推广
  • 饮料网站建设价格google推广一年3万的效果
  • ui设计做兼职的网站教育培训网站官网
  • 南通网站建设方案电影站的seo
  • 开封网站建设价格搜索引擎网站
  • 成都企业网站商城定制网络营销咨询服务
  • 深圳最大的招聘网站是什么外贸营销网站制作
  • 长沙铭万做网站徐州关键词优化排名
  • 自适应网站教程贵港seo