读写锁是用来解决读者写者问题的,读操作可以共享,写操作是排他的,读可以有多个在读,写只有唯一个在写,同时写的时候不允许读。

互斥锁与读写锁的区别:

当访问临界区资源时(访问的含义包括所有的操作:读和写),需要上互斥锁;

当对数据(互斥锁中的临界区资源)进行读取时,需要上读取锁,当对数据进行写入时,需要上写入锁。

读写锁的优点:

对于读数据比修改数据频繁的应用,用读写锁代替互斥锁可以提高效率。因为使用互斥锁时,即使是读出数据(相当于操作临界区资源)都要上互斥锁,而采用读写锁,则可以在任一时刻允许多个读出者存在,提高了更高的并发度,同时在某个写入者修改数据期间保护该数据,以免任何其它读出者或写入者的干扰。

读者-写者问题和生产者-消费者问题不同的是,后者的每个线程都要修改缓冲区的内容,所以不得不使用互斥锁来保证数据一致性,而前者有些线程是只读的,多个只读线程同时访问并不会出现数据不一致的情况,所以在实现上不必为每个线程都加一个互斥锁,而是让多个读线程可以同时访问,只有写进程的访问是互斥的。

这一篇博文写的很详细: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 | 读写锁【摘】的更多相关文章

  1. Go基础系列:互斥锁Mutex和读写锁RWMutex用法详述

    sync.Mutex Go中使用sync.Mutex类型实现mutex(排他锁.互斥锁).在源代码的sync/mutex.go文件中,有如下定义: // A Mutex is a mutual exc ...

  2. linux 一个读写锁的异常导致的故障

    环境信息: WARNING: kernel version inconsistency between vmlinux and dumpfile KERNEL: vmlinux-47.90 DUMPF ...

  3. Java并发(8)- 读写锁中的性能之王:StampedLock

    在上一篇<你真的懂ReentrantReadWriteLock吗?>中我给大家留了一个引子,一个更高效同时可以避免写饥饿的读写锁---StampedLock.StampedLock实现了不 ...

  4. golang互斥锁和读写锁

    一.互斥锁 互斥锁是传统的并发程序对共享资源进行访问控制的主要手段.它由标准库代码包sync中的Mutex结构体类型代表.sync.Mutex类型(确切地说,是*sync.Mutex类型)只有两个公开 ...

  5. 技术笔记:Delphi多线程应用读写锁

    在多线程应用中锁是一个很简单又很复杂的技术,之所以要用到锁是因为在多进程/线程环境下,一段代码可能会被同时访问到,如果这段代码涉及到了共享资源(数据)就需要保证数据的正确性.也就是所谓的线程安全.之前 ...

  6. java多线程-读写锁

    Java5 在 java.util.concurrent 包中已经包含了读写锁.尽管如此,我们还是应该了解其实现背后的原理. 读/写锁的 Java 实现(Read / Write Lock Java ...

  7. 让C#轻松实现读写锁分离

    ReaderWriterLockSlim 类 表示用于管理资源访问的锁定状态,可实现多线程读取或进行独占式写入访问. 使用 ReaderWriterLockSlim 来保护由多个线程读取但每次只采用一 ...

  8. C#读写锁ReaderWriterLockSlim的使用

    读写锁的概念很简单,允许多个线程同时获取读锁,但同一时间只允许一个线程获得写锁,因此也称作共享-独占锁.在C#中,推荐使用ReaderWriterLockSlim类来完成读写锁的功能. 某些场合下,对 ...

  9. 可重入锁 公平锁 读写锁、CLH队列、CLH队列锁、自旋锁、排队自旋锁、MCS锁、CLH锁

    1.可重入锁 如果锁具备可重入性,则称作为可重入锁. ========================================== (转)可重入和不可重入 2011-10-04 21:38 这 ...

随机推荐

  1. HDU 5510 Bazinga (字符串匹配)

    题目:传送门. 题意:t 组数据,每组 n 个串,对于第 i 个串如果存在 1 到 i-1 中的某个串不是 i 的子串,那么这个第 i 个串符合题意,求 i 的最大值. 题解:KMP,AC自动机也可以 ...

  2. MFC 文件按行读写 CStdioFile

    //写文件 CStdioFile file; file.Open("test.txt",CFile::modeCreate|CFile::modeReadWrite); file. ...

  3. unix PS命令和JPS命令的区别

    1.JPS介绍 用来查看基于HotSpot的JVM里面中,所有具有访问权限的Java进程的具体状态, 包括进程ID,进程启动的路径及启动参数等等,与unix上的ps类似,只不过jps是用来显示java ...

  4. .NET生成word文档服务器配置常见问题

    注意:安装office2003的时候一定要选择 "完全安装" 而不是 "典型安装" 错误:System.Runtime.InteropServices.COME ...

  5. [转]Java多线程编程的常见陷阱

    1.在构造函数中启动线程 我在很多代码中都看到这样的问题,在构造函数中启动一个线程,类似这样: public class A{ public A(){ this.x=1; this.y=2; this ...

  6. Ubuntu下中文显示乱码

    转自:http://jingyan.baidu.com/article/915fc414c9d2ef51384b204c.html 装好了Ubuntu 13.10 后,打开部分Windows下的txt ...

  7. FileHelper-文件操作辅助类

    using System; using System.Collections.Generic; using System.IO; using System.Text; namespace Whir.S ...

  8. nohup之no hang up, kill, ps -ef, ps aux, grep

    背景:今天在安装hudson时,每次启动时都必须在linux终端(SecureCRT)执行: java -jar hudson.war --httpPort=18080 --jp13Port=1800 ...

  9. more命令

    more 命令 用于分屏显示 more命令一般用于显示内容超过一屏的文件.其他命令经常和more匹配使用,但more命令也客单独使用. (1)其他命令和more命令匹配使用: 格式:    其他命令格 ...

  10. calendar 示例

    package unit5; import java.text.DateFormatSymbols; public class MyMonth { private int month; private ...