多线程的那点儿事(之读写锁)

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

    (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.   
  5.     assert(NULL != hRead && NULL != hWrite);  
  6.     pRwLock = (RWLock*)malloc(sizeof(RWLock));  
  7.     
  8.     pRwLock->hRead = hRead;  
  9.     pRwLock->hWrite = hWrite;  
  10.     pRwLock->count = 0;  
  11.     pRwLock->state = STATE_EMPTY;  
  12.     return pRwLock;  
  13. }  
     (3)获取读锁

[cpp] view plaincopy
  1. void read_lock(RWLock* pRwLock)  
  2. {  
  3.     assert(NULL != pRwLock);  
  4.       
  5.     WaitForSingleObject(pRwLock->hRead, INFINITE);  
  6.     pRwLock->counnt ++;  
  7.     if(1 == pRwLock->count){  
  8.         WaitForSingleObject(pRwLock->hWrite, INFINITE);  
  9.         pRwLock->state = STATE_READ;  
  10.     }  
  11.     ReleaseMutex(pRwLock->hRead);  
  12. }  
     (4)获取写锁
[cpp] view plaincopy
  1. void write_lock(RWLock* pRwLock)  
  2. {  
  3.     assert(NULL != pRwLock);  
  4.   
  5.     WaitForSingleObject(pRwLock->hWrite, INFINITE);  
  6.     pRwLock->state = STATE_WRITE;  
  7. }  
     (5)释放读写锁
[cpp] view plaincopy
  1. void read_write_unlock(RWLock* pRwLock)  
  2. {  
  3.     assert(NULL != pRwLock);  
  4.   
  5.     if(STATE_READ == pRwLock->state){  
  6.         WaitForSingleObject(pRwLock->hRead, INFINITE);  
  7.         pRwLock->count --;  
  8.         if(0 == pRwLock->count){  
  9.             pRwLock->state = STATE_EMPTY;  
  10.             ReleaseMutex(pRwLock->hWrite);  
  11.         }  
  12.         ReleaseMutex(pRwLock->hRead);  
  13.     }else{  
  14.         pRwLock->state = STATE_EMPTY;  
  15.         ReleaseMutex(pRwLock->hWrite);  
  16.     }  
  17.       
  18.     return;  
  19. }  

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/458543.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

iOS获取设备IP

获取iOS设备IP wifi和流量环境下 在网上找的比较好的获取ip的代码 #include <ifaddrs.h> #include <arpa/inet.h> #include <net/if.h> #define IOS_CELLULAR "pdp_ip0" #define IOS_WIFI "en0" #define IOS_VPN …

一些不错的网站

http://www.huxiu.com/虎嗅网&#xff0c;一个关注最新创业信息的网站http://36kr.com/创业天花板https://www.zhihu.com/与世界分享你的经验http://www.mafengwo.cn/世界那么大&#xff0c;想去哪就去那http://www.mt-bbs.com/找到属于自己的设计本http://www.guokr.com/科技有…

[原]详解如何将cocos2dx项目编译到Android平台上的(方式一:Cywin+NDK)

链接地址&#xff1a;http://m.blog.csdn.net/blog/yhc13429826359/29357815 2014-6-8阅读578 评论0 前言&#xff1a;cocos2dx作为一个开源的移动2D游戏框架&#xff0c;其跨平台的特性让它备受开发公司的欢迎。这里我就不做概念性的解释了&#xff0c;通过这篇文章你就会了解…

互斥锁和读写锁的区别

原文地址&#xff1a;http://blog.csdn.NET/u012884354/article/details/46691761 相交进程之间的关系主要有两种&#xff0c;同步与互斥。 所谓互斥&#xff0c;是指散布在不同进程之间的若干程序片断&#xff0c;当某个进程运行其中一个程序片段时&#xff0c;其它进程就不能…

JSP EL表达式使用

为什么80%的码农都做不了架构师&#xff1f;>>> ##1.EL全名为Expression Language out.print(str) <%str%> ${str}例子&#xff1a; Hi! <%username%> 和 Hi! ${username}是一样的 只要是支持servlet2.4/jsp2.0的Container就都可以在jsp网页中直接使用e…

eclipse 中 Android sdk 无法更新的问题

诶&#xff0c;真是麻烦&#xff0c;想下个东西都下不了。我也好久没折腾过这个了&#xff0c;在家的电脑是早就下载好了的&#xff0c;然后如今又须要下载一份。下不到。网上搜到了资料&#xff0c;记录下来&#xff1a; 第一种方法:sdk manager - tools - option 选择强制 xx…

iOS10 xcode8 分页请求MJRefresh崩溃问题

MJRefresh出现崩溃现象 解决办法&#xff1a;类库增加判断 if (range.location ! NSNotFound) { language [language substringToIndex:range.location]; }

网络编程学习笔记一:Socket编程

from: http://blog.csdn.net/gneveek/article/details/8699198 “一切皆Socket&#xff01;” 话虽些许夸张&#xff0c;但是事实也是&#xff0c;现在的网络编程几乎都是用的socket。 ——有感于实际编程和开源项目研究。 我们深谙信息交流的价值&#xff0c;那网络中进程之间…

JavaScript原生对象常用方法总结

这是4年前学习JavaScript基础的学习笔记&#xff0c;当初是照着W3School教程学习的&#xff0c;4年恍然如云烟&#xff0c;仿佛还在昨天。现发布与此&#xff0c;留作纪念&#xff0c;纪念那段不悔的青葱岁月。下面都是我学习W3C School教程中有关JavaScript写的学习笔记&#…

[delphi]修改indy源码后重新编译

http://blog.csdn.net/nerdy/article/details/8702568 虽然indy有一身的毛病&#xff0c;但是一般情况下使用起来还是多方便的。 今天在做一个使用到indy的程序的时候&#xff0c;发现无论你怎么修改idhttp.request.accept-encoding&#xff0c;他都会在其后添加一个值 identit…

xcode8 崩溃问题

【1】、Xcode8代码出现ubsystem: com.apple.UIKit, category: HIDEventFiltered, enable_level: 0, persist_level: 0, default_ttl: 0, info_ttl: 0, debug_ttl: 0, generate_symptoms: 0, enable_oversize: 1, privacy_setting: 2, enable_private_data: 0 2016-09-14 17:18:…

前端工具--less篇

前端工具–less篇 less 中文网http://www.bootcss.com/p/lesscss/ 常见错误及解决&#xff1a; sublime text 3 安装less2css保存less出现错误 未安装这个 npm install -g less-plugin-clean-css 未安装这个 npm install less -gd less语法 LESS 做为 CSS 的一种形式的扩展&a…

从static变量导出问题解析 __declspec(dllexport) 和 __declspec(dllimport)的作用

这段时间要把tinyxml从静态库弄成动态库&#xff0c;要用到__declspec(dllexport)和__declspec(dllimport)来导出dll和lib文件。终于弄明白了export和import的作用&#xff0c;下面从使用的角度来说明一下他们的功能。 首先要知道&#xff0c;头文件是C的接口文件&#xff0c;不…

4月26日作业

2016年4月26日作业 一、项目整体绩效评估1、*三E审计是什么的合称&#xff1f;&#xff08;记&#xff09; 答&#xff1a;经济审计&#xff0c;效率审计和效果审计2、霍尔三维结构是从哪三个方面考察系统工程的工作过程的&#xff1f; 答&#xff1a;逻辑&#xff0c;时间和知…

xcode8 快捷键失效

因为苹果解决xcode ghost,把插件屏蔽了。 解决方法: 命令运行&#xff1a; sudo /usr/libexec/xpccachectl 然后必须重启电脑后生效

CAS单点登录配置[3]:服务器端配置

在准备工作&#xff0c;证书生成等工作完成后&#xff0c;本篇介绍服务器端的配置。 JDK配置 1我们将生成的cacerts文件分别拷贝到JDK目录下的jre/lib/security目录下及JRE对应的目录中&#xff0c;如果之前存在此文件&#xff0c;请替换&#xff1b; ENDTomcat配置 1Step 1:将…

DLL动态链接库的工作原理

"动态链接"这几字指明了DLLs是如何工作的。 对于常规的函数库&#xff0c;链接器从中拷贝它需要的所有库函数&#xff0c;并把确切的函数地址传送给调用这些函数的程序。 而对于DLLs&#xff0c;函数储存在一个独立的动态链接库文件中。在创建Windows程序时&#xff…

remind程序

2019独角兽企业重金招聘Python工程师标准>>> 用了两个定时器。一个控制刷新时间&#xff0c;一个控制响铃。 定时器响应函数Timer: int wk; if(nIDEvent1) { CTime tCTime::GetCurrentTime(); wkt.GetDayOfWeek()-1; m_mnt.Format("%Y 年 …

查看手机是否安装微信客户端

if (![[UIApplication sharedApplication]canOpenURL:[NSURL URLWithString:"weixin://"]] ) {[wcatBtn setHidden:YES];}

Caffe学习系列(7):solver及其配置

solver算是caffe的核心的核心&#xff0c;它协调着整个模型的运作。caffe程序运行必带的一个参数就是solver配置文件。运行代码一般为 # caffe train --solver*_slover.prototxt 在Deep Learning中&#xff0c;往往loss function是非凸的&#xff0c;没有解析解&#xff0c;我们…