linux 内核的另一个自旋锁 - 读写锁
除spinlock外,linux 内核还有一个自旋锁,名为arch_rwlock_t。它的头文件是qrwlock.h,包含在spinlock.h,头文件中对它全称为"Queue read/write lock"。这个锁只使用了两个成员变量就实现了读写锁。一个spinlock,以及一个整形锁变量。而spinlock就是这个Queue。
锁的原理是,当没有写意愿或写锁使用时,任意读锁可以并发。当有写意愿或写锁使用时,一切的读锁和写锁都必须进行排队。
arch_rwlock_t的锁变量虽然只是一个整形,但是却是一个压缩的复合数据。它包含了读锁,写锁。
读锁,为锁变量的高24位。只要读锁操作成功对读锁字段加1,就可以获得读锁。
写锁,为锁变量的低8位,包含3种状态,有写意愿,写锁使用中,以及无。
arch_rwlock_t巧妙地将读锁和写锁压缩在一个整形,可以通过原子指令同时对两个锁进行原子操作。不必另外设计一锁对锁变量操作进行保护。
arch_rwlock_t还巧妙地使用了spinlock的自旋和FIFO排队特性,实现了对读写的排队。
arch_rwlock_t的读操作使用atomic_add和atomic_sub支持多个读者对读锁的修改,并且可以与写操作相容。但当上读锁一瞬后发现有写意愿和写进行,就必须归还读锁,进行排队模式。排队的读锁操作,在轮到的时候也不是一步到位就可以成功上读锁。因为这时,有可能其它CPU刚发生的写锁意愿,尽管有其它读写在排队,但这时这个刚发生写锁意愿的CPU是不被排队所约束的。在这种情况下,读锁是不可以归还的,回这会让同样的情况历史重演,使整个排队阻塞不前。所以这个轮到的排队读锁的CPU必须保持这个读锁,直到横刀插入的写锁释放后,马上通行。
reader | rwlock | writer |
1. 从spinlock排队返回 | read == 0 && write state == 0 | |
read == 0 && write state == FF | 1. 刚发起写锁操作,atomic_xchg返回的读锁字段仍为0,OK,没有读锁进行 | |
2. atomic_add返回,发现写锁字段不为0 | read == 1 && write state == FF | 2. 使用写锁 |
3. 自旋等待write state变为0 | ||
read == 1 && write state == 0 | 3. 归还写锁。即使突然发生的写锁操作也不能横刀断入(steal),只好去排队。 | |
4. 马上可以读锁能行。 | ||
5. 释放spinlock,使spinlock排队前进。 | ||
arch_rwlock_t的读操作使用atomic_cmpxchg保证只有一个写者完整进行写锁的修改,并且操作与任意读操作不相容,即有任意读操作同时进行,修改都不被接受。当有写意愿或写锁进行时,所有的写锁操作都必须和读锁操作平等地FIFO排队等候。只有在一个写锁操作发现有读锁进行时,进入排队发出写意愿(修改锁变量的写锁字段),这时候这个写锁操作才会成为第一个排队的操作,优先于其它后继的排队的操作。后继的排队的不论读锁或写锁的操作都是平等的。
spinlock不是用来保护锁变量,而是同步临界区queue_read_lock_slowpath以及queue_write_lock_slowpath的,对有写锁操作参与这一事态,进行对锁操作的排队。
linux 内核的另一个自旋锁 - 读写锁的更多相关文章
- Linux内核的同步机制---自旋锁
自旋锁的思考:http://bbs.chinaunix.net/thread-2333160-1-1.html 近期在看宋宝华的<设备驱动开发具体解释>第二版.看到自旋锁的部分,有些疑惑. ...
- 鸿蒙内核源码分析(自旋锁篇) | 当立贞节牌坊的好同志 | 百篇博客分析OpenHarmony源码 | v26.02
百篇博客系列篇.本篇为: v26.xx 鸿蒙内核源码分析(自旋锁篇) | 当立贞节牌坊的好同志 | 51.c.h .o 进程通讯相关篇为: v26.xx 鸿蒙内核源码分析(自旋锁篇) | 当立贞节牌坊 ...
- 可重入锁 公平锁 读写锁、CLH队列、CLH队列锁、自旋锁、排队自旋锁、MCS锁、CLH锁
1.可重入锁 如果锁具备可重入性,则称作为可重入锁. ========================================== (转)可重入和不可重入 2011-10-04 21:38 这 ...
- Linux内核分析-构造一个简单的Linux系统MenuOS
构造一个简单的Linux系统MenuOS linux内核目录结构 arch目录包括了所有和体系结构相关的核心代码.它下面的每一个子目录都代表一种Linux支持的体系结构,例如i386就是Intel C ...
- Linux 内核:匠心独运之无锁环形队列kfifo
Linux 内核:匠心独运之无锁环形队列 Kernel version Linux 2.6.12 Author Toney Email vip_13031075266@163.com Da ...
- Linux内核分析— —构造一个简单的Linux系统MenuOS(20135213林涵锦)
Linux内核分析— —构造一个简单的Linux系统MenuOS 实验内容 Linux内核的启动过程,从start_kernel到init进程启动 使用实验楼的虚拟机打开shell cd LinuxK ...
- Java并发-显式锁篇【可重入锁+读写锁】
作者:汤圆 个人博客:javalover.cc 前言 在前面并发的开篇,我们介绍过内置锁synchronized: 这节我们再介绍下显式锁Lock 显式锁包括:可重入锁ReentrantLock.读写 ...
- 使用ZooKeeper实现Java跨JVM的分布式锁(读写锁)
一.使用ZooKeeper实现Java跨JVM的分布式锁 二.使用ZooKeeper实现Java跨JVM的分布式锁(优化构思) 三.使用ZooKeeper实现Java跨JVM的分布式锁(读写锁) 读写 ...
- Linux内核RCU(Read Copy Update)锁简析
在非常早曾经,大概是2009年的时候.写过一篇关于Linux RCU锁的文章<RCU锁在linux内核的演变>,如今我承认.那个时候我尽管懂了RCU锁,可是我没有能力用一种非常easy的描 ...
随机推荐
- JavaScript-变量的作用域面试题
块级作用域 - 在其他的语言中,任何一对花括号中的语句都属于一个块,在这之中定义的所有变量在代码块外是不可见的 - JavaScript中没有块级作用域 //这里只有函数中定义的变 ...
- oracle监听(lsnrctl)详解解读
(总结)Oracle监听服务lsnrctl参数及查询状态详解 lsnrctl命令常用参数详解: lsnrctlstart启动指定的监听器 stop关闭指定的监听器 status显示监听器的状态.s ...
- Webpack 速成
前言 如果你已经对Webpack精通了或者至少一直在工作中使用它,请关闭当前浏览器标签,无视这篇文章. 这篇文章本意是写给我自己看的,作为一篇Cookbook供快速查询和上手用.原因是虽然工作中会涉及 ...
- GWT开端
这篇文章是转载的,原地址:GWT开端 以前的基于GWT的项目中广泛使用的还是gwt-windows-1.5.3这个版本的. 1.下载地址:http://code.google.com/webtoolk ...
- 自动化监控利器-Zabbix深入配置和使用
1. 配置流程 Zabbix完整的监控配置流程可以简单描述为: Host groups(主机组)→Hosts(主机)→Applications(监控项组)→Items(监控项)→Triggers(触 ...
- POJ1275出纳员的雇佣【差分约束】
出纳员的雇佣 Tehran的一家每天24小时营业的超市,需要一批出纳员来满足它的需要.超市经理雇佣你来帮他解决问题:超市在每天的不同时段需要不同数目的出纳员(例如:午夜时只需一小批,而下午则需要很多) ...
- GNU/Linux与开源文化的那些人和事
一.计算机的发明 世上本无路,走的人多了,就有了路.世上本无计算机,琢磨的人多了--没有计算机,一切无从谈起. 三个人对计算机的发明功不可没,居功至伟.阿兰·图灵(Alan Mathison Tur ...
- 随机跳转页面之使用VBA公共变量
p{ font-size: 15px; } .alexrootdiv>div{ background: #eeeeee; border: 1px solid #aaa; width: 99%; ...
- Best Time to Buy and Sell Stock系列
I题 Say you have an array for which the ith element is the price of a given stock on day i. If you we ...
- Flex——弹性布局
今天在做项目时,要一个500*100的页面区域做三个橱窗,尼玛可是恶心死我了!光是计算左右内外边距,左右宽度,就废了一上午时间~~好吧,我承认我的数学老师挂得早! 正在苦逼的列公式,定位图片,浮动文字 ...