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

(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. java安全编码实践总结
  3. 做一个java项目要经过那些正规的步骤
  4. 7天后自动更新cookie
  5. 装饰器模式与代理模式的区别_JS设计模式(三):装饰器模式、代理模式
  6. 桌面桌面虚拟化-Vmware horizon 7相关文件共享
  7. java innodb存储引擎_InnoDB存储引擎简介
  8. mysql数据库 uft8_unicode_ci是utf8吗_MysQL数据库中utf8_unicode_ci与utf8_general_ci的区别
  9. Using Java SecurityManager to grant/deny access to system functions
  10. C语言:从入门到进阶笔记(完整版)
  11. 匈牙利算法python实现
  12. LeetCode 75. Sort Colors(三颜色排序→K颜色排序)
  13. 远程重装Win11系统图文教程
  14. EXCEL-日常技巧整理-2-单元格拆分后原数据填充
  15. java7 diamond_java7新特性之Diamond syntax
  16. 听比喻,懂原理(1)超五类双绞线和六类双绞线的区别
  17. git使用大全,强大的项目管理工具
  18. potplayer清晰度设置
  19. 修改win10更新服务器地址,Windows 10 更新缓存位置能否修改
  20. C# 图片格式转换的实例代码

热门文章

  1. 修改jquery文件上传插件uploadify的英文为中文
  2. Liunx安装gogs,mysql,jdk,tomcat等常用软件
  3. 深入剖析ThreadLocal实现原理以及内存泄漏问题
  4. Hibernate二级缓存配置
  5. Github基本操作的学习与温习
  6. [转]深入理解linux内核list_head
  7. 【DFS】NYOJ-325-zb的生日
  8. 高效管理ASP.NET的JavaScript库
  9. @Java | Thread synchronized - [ 线程同步锁 基本使用]
  10. 读书笔记2013第3本:《无价》