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 这 ...
随机推荐
- DP:Making the Grade(POJ 3666)
聪明的修路方案 题目大意:就是农夫要修一条路,现在要求这条路要么就是上升的,要么就是下降的,总代价为∑|a[i]-b[i]|,求代价最低的修路方案, (0 ≤ β≤ 1,000,000,000) , ...
- 侃侃前端MVC设计模式
前言 前端的MVC,近几年一直很火,大家也都纷纷讨论着,于是乎,抽空总结一下这个知识点.看了些文章,结合实践略作总结并发表一下自己的看法. 最初接触MVC是后端Java的MVC架构,用一张图来表示之— ...
- 开启InnoDB每表一个独立的表空间
mysql> show variables like '%innodb%'; +---------------------------------+----------------------- ...
- Java开发中程序和代码性能优化
现在计算机的处理性能越来越好,加上JDK升级对一些代码的优化,在代码层针对一些细节进行调整可能看不到性能的明显提升, 但是我觉得在开发中注意这些,更多的是可以保持一种性能优先的意识,对一些敲代码时间比 ...
- oracle 10g 学习之触发器(13)
真实使用场景:数据备份 1. 触发器的 helloworld: 编写一个触发器, 在向 emp 表中插入记录时, 打印 'helloworld' create or replace trigger e ...
- svn服务端hooks钩子可用于多项目自动同步
废话不多说,直接上post-commit脚本了: 日志会全部记录下来包括同步的文件 vim post-commit #!/bin/sh REPOS="$1" # 仓库的路径 REV ...
- Angular中的Error: [$resource:badcfg]错误如何解决之一种
相信这种情况很多的吧,我遇到的情况是因为在作reSource的service时,query出来的协议不对. 错误时候的代码: Version.factory("versionSrv" ...
- 面向服务的体系结构(SOA)——(5)关于MEP(Message Exchange Patterns)
SOA中的MEP和JavaEE中的JMS类似,当然了就应该是类似的,因为都是关于消息方面的.一个是对系统架构当中消息的解决思路,一个是针对Java平台中的消息的具体解决办法(严格说不是具体的,只是提供 ...
- C语言位运算详解(转载)
转载自:http://www.cnblogs.com/911/archive/2008/05/20/1203477.html 位运算是指按二进制进行的运算.在系统软件中,常常需要处理二进制位的问题.C ...
- Android Inflate
inflate就相当于将一个xml中定义的布局找出来. 三种方式可以生成LayoutInflater: LayoutInflaterinflater=LayoutInflater.from(this) ...