读写锁在对资源进行保护的同时,还能区分想要读取资源值的线程(读取者线程)和想要更新资源的线程(写入者线程)。

对于读取者线程,读写锁会允许他们并发的执行。当有写入者线程在占有资源时,读写锁会让其它写入者线程和读取者线程等待。

因此用读写锁来解决读者写者问题会使代码非常清晰和简洁。

SRWLock 允许我们区分那些想要读取资源的值的线程(读取者线程)和想要更新资源值的线程(写入者线程)

       所有的读取者线程在同一时刻访问共享资源是可以的,这是因为仅仅读取资源的值并不存在破坏数据的风险。

       只有当写入者线程想要对资源进行更新的时候才需要同步。

       在这种情况下,写入者线程应该独占对资源的访问权: 任何其他线程,无论是读取者线程还是写入者线程,都不允许访问资源。

相关函数介绍:

第一个 InitializeSRWLock

函数功能:初始化读写锁

函数原型:VOID InitializeSRWLock(PSRWLOCK SRWLock);

函数说明:初始化(没有删除或销毁SRWLOCK的函数,系统会自动清理)

第二个 AcquireSRWLockExclusive

函数功能:写入者线程申请写资源。

函数原型:VOID AcquireSRWLockExclusive(PSRWLOCK SRWLock);

第三个 ReleaseSRWLockExclusive

函数功能:写入者线程写资源完毕,释放对资源的占用。

函数原型:VOID ReleaseSRWLockExclusive(PSRWLOCK SRWLock);

第四个 AcquireSRWLockShared

函数功能:读取者线程申请读资源。

函数原型:VOID AcquireSRWLockShared(PSRWLOCK SRWLock);

第五个 ReleaseSRWLockShared

函数功能:读取者线程结束读取资源,释放对资源的占用。

函数原型:VOID ReleaseSRWLockShared(PSRWLOCK SRWLock);

注意一个线程仅能锁定资源一次,不能多次锁定资源。

实例代码如下:

#include <iostream>
#include <windows.h>
#include <process.h>using namespace std;const int NUM = 30, READER_SIZE = 10;
HANDLE thread_r[NUM], thread_o[NUM], thread_w[NUM];
CRITICAL_SECTION sc, oc;
SRWLOCK rwLock;unsigned int __stdcall read(PVOID pm) {AcquireSRWLockShared(&rwLock);    EnterCriticalSection(&sc);cout << GetCurrentThreadId() << "号,读进程开始..." << endl;LeaveCriticalSection(&sc);Sleep(rand() % 100);EnterCriticalSection(&sc);cout << GetCurrentThreadId() << "号,读进程结束..." << endl;LeaveCriticalSection(&sc);ReleaseSRWLockShared(&rwLock);return 0;
}unsigned int __stdcall write(PVOID pm) {AcquireSRWLockExclusive(&rwLock);cout << GetCurrentThreadId() << "号,--------------写进程开始..." << endl;Sleep(rand() % 100);cout << GetCurrentThreadId() << "号,--------------写进程执行完毕..." << endl;ReleaseSRWLockExclusive(&rwLock);return 0;
}int main() {InitializeCriticalSection(&sc);InitializeCriticalSection(&oc);InitializeSRWLock(&rwLock);int i = 0;for(; i<NUM; i++) {thread_r[i] = (HANDLE) _beginthreadex(NULL, 0, read, NULL, 0, NULL);thread_w[i] = (HANDLE) _beginthreadex(NULL, 0, write, NULL, 0, NULL);}WaitForMultipleObjects(NUM, thread_r, TRUE, INFINITE);
//  Sleep(100);// 在执行30个 读线程for(i=0; i<NUM; i++) {thread_o[i] = (HANDLE) _beginthreadex(NULL, 0, read, NULL, 0, NULL);}
//  writeLock = true;WaitForMultipleObjects(NUM, thread_w, TRUE, INFINITE);WaitForMultipleObjects(NUM, thread_o, TRUE, INFINITE);DeleteCriticalSection(&sc);DeleteCriticalSection(&oc);cout << "运行完毕" << endl;getchar();return 0;
}

运行效果如下:





总结一下读写锁SRWLock

1.读写锁声明后要初始化,但不用销毁,系统会自动清理读写锁。

2.读取者和写入者分别调用不同的申请函数和释放函数。

读写锁SRWLock相关推荐

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

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

  2. php 读锁,php文件读写锁

    $file = fopen("test.txt", $fileOpenMode); flock($file, $lockMode) or die("Can't lock& ...

  3. linux 进程 读写锁,linux 下实现高性能读写锁(read/write lock)

    前一篇文章分析了Windows slim read/write lock的工作原理.我们知道它的设计相当精妙,于是我们可以借鉴它的思路来设计linux下的读写锁. 在这个读写锁的设计上,需要注意的是l ...

  4. Windows编程——读写锁

    前言 在Windows上使用读写锁很方便,只需要了解几个非常简单的API即可使用,可能只需要花上数分钟而已,在这点上与Linux无异! 简介 众所周知,多线程不能同时读写某段内存,但可以共享读,在这种 ...

  5. 轻量级 读写锁(SRW)

    看了 MoreWindows 的Blog, 自己实践了下, 写写总结, 记录下.并在此谢谢那些无私的大牛们  Orz ========================================= ...

  6. java锁(公平锁和非公平锁、可重入锁(又名递归锁)、自旋锁、独占锁(写)/共享锁(读)/互斥锁、读写锁)

    前言 本文对Java的一些锁的概念和实现做个整理,涉及:公平锁和非公平锁.可重入锁(又名递归锁).自旋锁.独占锁(写)/共享锁(读)/互斥锁.读写锁 公平锁和非公平锁 概念 公平锁是指多个线程按照申请 ...

  7. ReentrantReadWriteLock读写锁的使用

    Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象.两个线程执行的代码片段要实现同步互斥的效果,它们必须用同一个Lock对象. 读写锁:分为读 ...

  8. golang:1.并发编程之互斥锁、读写锁详解

    本文转载自junjie,而后稍作修改. 一.互斥锁 互斥锁是传统的并发程序对共享资源进行访问控制的主要手段.它由标准库代码包sync中的Mutex结构体类型代表.sync.Mutex类型(确切地说,是 ...

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

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

最新文章

  1. python ssh模块有哪些_Python paramiko模块(实现ssh)
  2. 【周末阅读】你不得不知道的10大AI赋能行业,你身边都能找到!
  3. 得到当前数据库中所有用户表信息
  4. 经典SQL短小代码收集汇总
  5. java怎么输出集合_Java 输出集合中的元素
  6. 几个关于财报的基本知识
  7. python中lambda函数_python中的lambda函数用法
  8. 作者:刘新海(1976-),男,中国人民银行征信中心副研究员
  9. java对象说明 PO,BO,VO,DTO,POJO,DAO,Entity
  10. Unity3D游戏开发入门引导:Unity3D收费方案和版本、下载地址、安装教程
  11. 牛顿迭代法求解根号a的Matlab代码
  12. Deepo:几乎包含所有主流深度学习框架的Docker镜像
  13. 【Word】去掉“项目符号/编号”之后的制表符
  14. java基础/接口与继承1(0.96万字)
  15. 基于C#实现的小型动物识别推理系统
  16. excel文档打不开怎么修复?
  17. PHP代码审计18—PHP代码审计小结
  18. linux下磁盘sda,Linux下磁盘设备文件(sda,sdb,sdc….)变化的问题
  19. 关于 人工智能 的思考
  20. appcan.frame.open打开的浮空窗口页面不开启弹动的情况下,也会有微微的滑动bug...

热门文章

  1. 【原创】自定义Appender类,输出DCMTK日志
  2. Qt实现表格内进度条展示数据
  3. Hadoop完全分布式部署
  4. PYthon常用模块 logging 日志
  5. System.Convert 的一些事
  6. Python一课一练(网站项目做单元测试)
  7. WPF的ControlTemplate和DataTemplate简介
  8. 词法分析程序 LEX和VC6整合使用的一个简单例子
  9. Java并发编程笔记—摘抄—基础知识
  10. 应用程序正在为首次使用计算机做准备