在编写多线程的时候,有一种情况是十分常见的。那就是,有些公共数据修改的机会比较少。相比较改写,它们读的机会反而高的多。通常而言,在读的过程中,往往伴随着查找的操作,中间耗时很长。给这种代码段加锁,会极大地降低我们程序的效率。那么有没有一种方法,可以专门处理这种多读少写的情况呢?
    有,那就是读写锁。

(1)首先,我们定义一下基本的数据结构。

[cpp] view plaincopy
  1. typedef struct _RWLock
  2. {
  3. int count;
  4. int state;
  5. HANDLE hRead;
  6. HANDLE hWrite;
  7. }RWLock;

同时,为了判断当前的锁是处于读状态,还是写状态,我们要定义一个枚举量,

[cpp] view plaincopy
  1. typedef enum
  2. {
  3. STATE_EMPTY = 0,
  4. STATE_READ,
  5. STATE_WRITE
  6. };

(2)初始化数据结构

[cpp] view plaincopy
  1. RWLock* create_read_write_lock(HANDLE hRead, HANDLE hWrite)
  2. {
  3. RWLock* pRwLock = NULL;
  4. assert(NULL != hRead && NULL != hWrite);
  5. pRwLock = (RWLock*)malloc(sizeof(RWLock));
  6. pRwLock->hRead = hRead;
  7. pRwLock->hWrite = hWrite;
  8. pRwLock->count = 0;
  9. pRwLock->state = STATE_EMPTY;
  10. return pRwLock;
  11. }

(3)获取读锁

[cpp] view plaincopy
  1. void read_lock(RWLock* pRwLock)
  2. {
  3. assert(NULL != pRwLock);
  4. WaitForSingleObject(pRwLock->hRead, INFINITE);
  5. pRwLock->counnt ++;
  6. if(1 == pRwLock->count){
  7. WaitForSingleObject(pRwLock->hWrite, INFINITE);
  8. pRwLock->state = STATE_READ;
  9. }
  10. ReleaseMutex(pRwLock->hRead);
  11. }

(4)获取写锁

[cpp] view plaincopy
  1. void write_lock(RWLock* pRwLock)
  2. {
  3. assert(NULL != pRwLock);
  4. WaitForSingleObject(pRwLock->hWrite, INFINITE);
  5. pRwLock->state = STATE_WRITE;
  6. }

(5)释放读写锁

[cpp] view plaincopy
  1. void read_write_unlock(RWLock* pRwLock)
  2. {
  3. assert(NULL != pRwLock);
  4. if(STATE_READ == pRwLock->state){
  5. WaitForSingleObject(pRwLock->hRead, INFINITE);
  6. pRwLock->count --;
  7. if(0 == pRwLock->count){
  8. pRwLock->state = STATE_EMPTY;
  9. ReleaseMutex(pRwLock->hWrite);
  10. }
  11. ReleaseMutex(pRwLock->hRead);
  12. }else{
  13. pRwLock->state = STATE_EMPTY;
  14. ReleaseMutex(pRwLock->hWrite);
  15. }
  16. return;
  17. }

文章总结:
    (1)读写锁的优势只有在多读少写、代码段运行时间长这两个条件下才会效率达到最大化;
    (2)任何公共数据的修改都必须在锁里面完成;
    (3)读写锁有自己的应用场所,选择合适的应用环境十分重要;
    (4)编写读写锁很容易出错,朋友们应该多加练习;
    (5)读锁和写锁一定要分开使用,否则达不到效果。

多线程的那点儿事(之读写锁)相关推荐

  1. 【C/C++多线程编程之九】pthread读写锁

    多线程编程之读写锁 Pthread是 POSIX threads 的简称,是POSIX的线程标准. pthread读写锁把对共享资源的访问者分为读者和写者,读者只对共享资源进行读访问,写者只对共享资源 ...

  2. 深入浅出多线程编程实战(九)读写锁ReentrantReadWriteLock

    文章目录 前言 一.ReadWriteLock 二.ReentrantReadWriteLock 1.特性 2.使用样例 结尾 前言 在前面的文章中我们介绍过两种锁:内置锁(synchronized) ...

  3. 多线程的那点儿事(之大结局)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 多线程一直是我比较喜欢的话题,当然也是很多朋友比较害怕的话题.喜欢它,因为它确实可以提高pc的 ...

  4. 怎么样用 Python 实现读写锁

    起步 Python 提供的多线程模型中并没有提供读写锁,读写锁相对于单纯的互斥锁,适用性更高,可以多个线程同时占用读模式的读写锁,但是只能一个线程占用写模式的读写锁. 通俗点说就是当没有写锁时,就可以 ...

  5. 面试必问!有没有比读写锁更快的锁?

    面试三连 面试官:了解锁吗? 小明:了解,还经常用过. 面试官:说说synchronized和lock的区别吧 小明:synchronized是可重入锁,由于lock是一个接口,重入性取决于实现,sy ...

  6. windows 读写锁 python_用Python实现读写锁的示例代码

    起步 Python 提供的多线程模型中并没有提供读写锁,读写锁相对于单纯的互斥锁,适用性更高,可以多个线程同时占用读模式的读写锁,但是只能一个线程占用写模式的读写锁. 通俗点说就是当没有写锁时,就可以 ...

  7. Linux多线程的同步------读写锁

    前面介绍过Linux多线程同步的另外两个方法------互斥锁和信号量 Linux多线程的同步-----信号量和互斥锁_神厨小福贵!的博客-CSDN博客 下面来看一下读写锁: 读写锁和互斥锁都带有一个 ...

  8. C#使用读写锁三行代码简单解决多线程并发写入文件时线程同步的问题

    在开发程序的过程中,难免少不了写入错误日志这个关键功能.实现这个功能,可以选择使用第三方日志插件,也可以选择使用数据库,还可以自己写个简单的方法把错误信息记录到日志文件. 选择最后一种方法实现的时候, ...

  9. 秒杀多线程第十四篇 读者写者问题继 读写锁SRWLock

    在<秒杀多线程第十一篇读者写者问题>文章中我们使用事件和一个记录读者个数的变量来解决读者写者问题.问题虽然得到了解决,但代码有点复杂.本篇将介绍一种新方法--读写锁SRWLock来解决这一 ...

最新文章

  1. 2 vtk 编译_OpenCV4.2使用viz模块显示3D图像
  2. 安装varish作为缓存和代理
  3. Tomcat中文乱码问题的原理和解决方法
  4. vc2010中开始执行不调试灰的_消防水炮调试,客户看到调试流程一刹那就满意
  5. 如何添加引文标_如何在Google文档中查找和添加引文
  6. .NET Core 工具中的新内容
  7. kd tree学习笔记 (最近邻域查询)
  8. python3.6找到不_sqlite3模块
  9. ActiveMq工作笔记001---Windows10下安装ActiveMq
  10. js map的get 和list比 那个快_js中let和var
  11. 关于html中css无法作用的问题
  12. text/x-jquery-tmpl做分页查询
  13. 七言 感大兴安岭大火
  14. 程序员教程第五版笔记
  15. Unity3D发布微信小程序
  16. Wireshark文档阅读笔记-TCP Flags
  17. 出没干日月鸿蒙之内翻译,李白《大鹏遇希有鸟赋》原文及翻译赏析
  18. 商场室内地图导航如何实现,便捷、低成本智慧商业综合体一站式解决方案
  19. “新主”难救美赞臣?
  20. Java AOP自定义注解

热门文章

  1. dubbo ,dubbo-provider、dubbo-consumer 配置参数说明
  2. PLSQL 安装+配置( Oracle数据库连接工具 )
  3. python读xml文件
  4. 解决pip安装模块报错Cannot fetch index base URL http://pypi.python.org/simple/
  5. MyBatis - MyBatis Generator 生成的example 如何使用 and or 简单混合查询
  6. 网络流(最大流) HDU 1565 方格取数(1) HDU 1569 方格取数(2)
  7. 写一个Android输入法01——最简步骤
  8. jmeter上传文件搞了一天,才搞定,没高人帮忙效率就是低,赶紧记下来,以备后用...
  9. 程序员必知8大排序3大查找(一)
  10. CMake 常用的预定义变量