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 这 ...
随机推荐
- Heap:Sunscreen(POJ 3614)
晒太阳 题目大意:一堆牛,为了避免晒太阳会灼烧自己,然后他们自己有自己的防晒指数(一个区间),防晒霜可以提高防晒因数SPF,大了不行小了不行,现在有一桶防晒霜,他们提供一定的SPF,但是最多可以提供k ...
- Powershell 批量替换文件
Powershell 批量替换文件 ##作者:Xiongpq ##时间:2015-06-10 18:50 ##版本:2.0 ##源文件目录 ##源文件目录的所有文件都会覆盖目标目录的同名文件,源文件目 ...
- DOS 循环读取txt每一行内容
在命令行窗口中输入: for /f %i in (f:\mydata.txt) do echo %i 如果要是写成批处理文件run.bat for /f %%i in (f:\mydata.txt) ...
- 解决 jersey javax.ws.rs.core.UriBuilder.fromUri(UriBuilder.java:119)
检查是否Jar冲突 保留一个jersey-server-*.jar
- Binary Search--二分查找
Binary Search--二分查找 采用二分法查找时,数据需是排好序的. 基本思想:假设数据是按升序排序的,对于给定值x,从序列的中间位置开始比较,如果当前位置值等于x,则查找成功:若x小于当前位 ...
- Struts2标签库
一. 写jsp页面的时候,在struts2中,用的是s标记,先引入标记: <%@ taglib prefix="s" uri="/struts-tags" ...
- sina发现并不会去导入qq使用的
看问题需要多角度,为之不能实现也是有可能没有完善的.确实是由于短时间发布过多,还是bky好点好像有30S
- ping: unknown host www.baidu.com
#注意有很多的DNS服务器 为了防止DDOS攻击 所以都禁止PING [root@86 ~]# ping -c 2 www.baidu.com ping: unknown host www.baidu ...
- .net学习笔记----HttpRequest类
一.HttpRequest的作用 HttpRequest的作用是令到Asp.net能够读取客户端发送HTTP值.比如表单.URL.Cookie传递过来的参数. 返回字符串的那些值就不说了,那些基本上都 ...
- 表现层(jsp)、持久层(类似dao)、业务层(逻辑层、service层)、模型(javabean)、控制层(action)
转自:http://www.blogjava.net/jiabao/archive/2007/04/08/109189.html 为了实现web层(struts)和持久层(Hibernate)之间的松 ...