OS | 读写锁【摘】
读写锁是用来解决读者写者问题的,读操作可以共享,写操作是排他的,读可以有多个在读,写只有唯一个在写,同时写的时候不允许读。
互斥锁与读写锁的区别:
当访问临界区资源时(访问的含义包括所有的操作:读和写),需要上互斥锁;
当对数据(互斥锁中的临界区资源)进行读取时,需要上读取锁,当对数据进行写入时,需要上写入锁。
读写锁的优点:
对于读数据比修改数据频繁的应用,用读写锁代替互斥锁可以提高效率。因为使用互斥锁时,即使是读出数据(相当于操作临界区资源)都要上互斥锁,而采用读写锁,则可以在任一时刻允许多个读出者存在,提高了更高的并发度,同时在某个写入者修改数据期间保护该数据,以免任何其它读出者或写入者的干扰。
读者-写者问题和生产者-消费者问题不同的是,后者的每个线程都要修改缓冲区的内容,所以不得不使用互斥锁来保证数据一致性,而前者有些线程是只读的,多个只读线程同时访问并不会出现数据不一致的情况,所以在实现上不必为每个线程都加一个互斥锁,而是让多个读线程可以同时访问,只有写进程的访问是互斥的。
这一篇博文写的很详细:http://ouonline.net/pthread-notes-3
写者优先的思考参考了:http://blog.csdn.net/yaozhiyi/article/details/7563869
读者优先:第一次读的时候获取锁,最后一次读的时候释放锁;这样只要有读操作,就不能写;
写者优先:
1. 对于写者:只要有写操作,就会尝试着去获取读锁,这样接下来的读就不能继续了,这样的尝试只需要一次,当没有写操作时就应该释放读锁。
2. 对于读者:只要有读操作,那么就尝试着去获取写锁,这样接下来的写也就不能继续,但是读者还是可以读;读操作会和写操作竞争读锁,这里确保了只有一个读操作和写操作竞争读锁;
关于写者优先,我的思路如下:
a. 需要写写互斥,所以需要下面的结构:
//写者
lock(&writeLock);
write();
unlock(&writeLock);
b. 需要读写互斥,所以:
//写者;并且只需要第一个写请求去获取读锁
lock(&writeCountLock);
writeCount++;
if (writeCount == ) lock(&readLock);
unlock(&writeCountLock); lock(&writeLock);
write();
unlock(&writeLock); unlock(&readLock); lock(&writeCountLock);
writeCount--;
if (writeCount == ) unlock(&readLock);
unlock(&writeCountLock);
//读者
lock(&readLock);
read();
unlock(&readLock);
c. 在读的时候,应该获取写锁,这样才能保证读的时候不写;但这是没有写操作时的处理;
//读者
lock(&readCountLock);
readCount++;
if (readCount == ) lock(&writeLock);
unlock(&readCountLock); read(); lock(&readCountLock);
readCount--;
if (readCount == ) unlock(&writeLock);
unlock(&readCountLock);
d. 如果此时有一个新的写操作,为了让它能够竞争到读锁,那么要让新来的read锁住,很明显就是在read()的前面要锁住,而且是和读锁相关,并且是限定了竞争时读的个数为1.所以加在Line2-5的外围。
// 读者
lock(&readLock);
lock(&readCountLock);
readCount++;
if (readCount == ) lock(&writeLock);
unlock(&readCountLock);
unlock(&readLock); read(); lock(&readCountLock);
readCount--;
if (readCount == ) unlock(&writeLock);
unlock(&readCountLock);
这样是能保证,没有新的读的时候,永远只是竞争一个读锁来更新readCount,然后read()这里是可以并行的。
OS | 读写锁【摘】的更多相关文章
- Go基础系列:互斥锁Mutex和读写锁RWMutex用法详述
sync.Mutex Go中使用sync.Mutex类型实现mutex(排他锁.互斥锁).在源代码的sync/mutex.go文件中,有如下定义: // A Mutex is a mutual exc ...
- linux 一个读写锁的异常导致的故障
环境信息: WARNING: kernel version inconsistency between vmlinux and dumpfile KERNEL: vmlinux-47.90 DUMPF ...
- Java并发(8)- 读写锁中的性能之王:StampedLock
在上一篇<你真的懂ReentrantReadWriteLock吗?>中我给大家留了一个引子,一个更高效同时可以避免写饥饿的读写锁---StampedLock.StampedLock实现了不 ...
- golang互斥锁和读写锁
一.互斥锁 互斥锁是传统的并发程序对共享资源进行访问控制的主要手段.它由标准库代码包sync中的Mutex结构体类型代表.sync.Mutex类型(确切地说,是*sync.Mutex类型)只有两个公开 ...
- 技术笔记:Delphi多线程应用读写锁
在多线程应用中锁是一个很简单又很复杂的技术,之所以要用到锁是因为在多进程/线程环境下,一段代码可能会被同时访问到,如果这段代码涉及到了共享资源(数据)就需要保证数据的正确性.也就是所谓的线程安全.之前 ...
- java多线程-读写锁
Java5 在 java.util.concurrent 包中已经包含了读写锁.尽管如此,我们还是应该了解其实现背后的原理. 读/写锁的 Java 实现(Read / Write Lock Java ...
- 让C#轻松实现读写锁分离
ReaderWriterLockSlim 类 表示用于管理资源访问的锁定状态,可实现多线程读取或进行独占式写入访问. 使用 ReaderWriterLockSlim 来保护由多个线程读取但每次只采用一 ...
- C#读写锁ReaderWriterLockSlim的使用
读写锁的概念很简单,允许多个线程同时获取读锁,但同一时间只允许一个线程获得写锁,因此也称作共享-独占锁.在C#中,推荐使用ReaderWriterLockSlim类来完成读写锁的功能. 某些场合下,对 ...
- 可重入锁 公平锁 读写锁、CLH队列、CLH队列锁、自旋锁、排队自旋锁、MCS锁、CLH锁
1.可重入锁 如果锁具备可重入性,则称作为可重入锁. ========================================== (转)可重入和不可重入 2011-10-04 21:38 这 ...
随机推荐
- Windows下的cmd命令行中设置环境编码
我们都知道,Windows下的cmd命令行默认编码是Windows系统的编码,就是ANSI编码或者说是GBK编码的,这样我们编写的很多应用比如php编写utf-8编码的应用在命令行下面运行时都会出现乱 ...
- 利用runTime,实现以模型为主的字典转模型(注意与KVC的区别)
将字典转化为模型,面向模型开发,是在开发中最为常用的功能.利用KVC可以将字典转换为模型,但是前提有三个约束,一个是必须保证模型的属性个数大于等于字典个数,二是属性名称与字典的key必须相同,三是对于 ...
- HDU 2841 Visible Trees 数论+容斥原理
H - Visible Trees Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u S ...
- Java Hour 28 HashSet
有句名言,叫做10000小时成为某一个领域的专家.姑且不辩论这句话是否正确,让我们到达10000小时的时候再回头来看吧. Hour 28 HashSet 为查找而生 LinkedList查找效率低下, ...
- jquery日期格式化
function dateFormat(date, format){ date = , ) / ), ) { v = ); } ...
- BroadcastReceiver应用详解(转)
转自: http://blog.csdn.net/liuhe688/article/details/6955668 問渠那得清如許?為有源頭活水來.南宋.朱熹<觀書有感> 据说程序员是最爱 ...
- 【Android】SlidingMenu属性详解(转)
原文:http://my.eoe.cn/1169143/archive/21892.html SlidingMenu简介:SlidingMenu的是一种比较新的设置界面或配置界面效果,在主界面左滑或者 ...
- 能加载文件或程序集“System.Data.SQLite”或它的某一个依赖项。试图加载格式不正确的程序。
现象: 能加载文件或程序集“System.Data.SQLite”或它的某一个依赖项.试图加载格式不正确的程序.
- javascript优化--10模式(设计模式)01
单体模式:保证一个特定类仅有一个实例;即第二次使用同一个类创建新对象时,应该得到与第一个所创建对象完全相同对象: 在JS中,可以认为每次在使用对象字面量创建对象的时候,实际上就在创建一个单体: 当使用 ...
- D FFF团的怒火
Time Limit:1000MS Memory Limit:65535K 题型: 编程题 语言: 无限制 描述 在信软学院,男女比例失衡已经是习以为常的事情. 在这样的一个学院,诞生了一个神秘 ...