读者写者问题继 读写锁SRWLock
在《秒杀多线程第十一篇读者写者问题》文章中我们使用事件和一个记录读者个数的变量来解决读者写者问题。问题虽然得到了解决,但代码有点复杂。本篇将介绍一种新方法——读写锁SRWLock来解决这一问题。读写锁在对资源进行保护的同时,还能区分想要读取资源值的线程(读取者线程)和想要更新资源的线程(写入者线程)。对于读取者线程,读写锁会允许他们并发的执行。当有写入者线程在占有资源时,读写锁会让其它写入者线程和读取者线程等待。因此用读写锁来解决读者写者问题会使代码非常清晰和简洁。
下面就来看看如何使用读写锁,要注意编译读写锁程序需要VS2008,运行读写锁程序要在Vista或Windows Server2008系统(比这两个更高级的系统也可以)。读写锁的主要函数就五个,分为初始化函数,写入者线程申请和释放函数,读取者线程申请和释放函数,以下是详细的函数使用说明:
第一个 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);
注意一个线程仅能锁定资源一次,不能多次锁定资源。
使用读写锁精简后的代码如下(代码中变参函数的实现请参阅《C,C++中使用可变参数》,控制台颜色设置请参阅《VC 控制台颜色设置》):
#include<stdio.h>
#include<process.h>
#include<Windows.h>
/*按照逻辑,即使是读文件线程先运行,也要一直阻塞到第一个写线程执行完(因为写线程不运行,就没有数据。此时,读线程的执行就没有意义)。*///设置控制台颜色输出
BOOL SetConsoleColor(WORD wAttributes)
{
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
if (hConsole == INVALID_HANDLE_VALUE)
return false;
return SetConsoleTextAttribute(hConsole, wAttributes);
}const int READER_NUM = 5;
CRITICAL_SECTION g_cs;
SRWLOCK g_srwLock;//读者线程输出函数(变参函数的实现)
void ReaderPrintf(char *pszFormat, ...)
{
va_list pArgList;
va_start(pArgList, pszFormat);
EnterCriticalSection(&g_cs);
vfprintf(stdout, pszFormat, pArgList);
LeaveCriticalSection(&g_cs);
va_end(pArgList);
}
//读者线程函数
unsigned int _stdcall ReaderThreadFun(PVOID pM)
{
ReaderPrintf(" 编号为%d的读者进入等待中...\n");
//读者申请读取文件
AcquireSRWLockShared(&g_srwLock);//读取文件
ReaderPrintf("编号为%d的读者开始读取文件...\n");
Sleep(rand() % 100);
ReaderPrintf("编号为%d的读者结束读取文件!\n");ReleaseSRWLockShared(&g_srwLock);
return 0;
}void WriterPrintf(char *pszStr)
{
EnterCriticalSection(&g_cs);
SetConsoleColor(FOREGROUND_GREEN);
printf(" %s\n", pszStr);
SetConsoleColor(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);
LeaveCriticalSection(&g_cs);
}
//写者函数
unsigned int _stdcall WriterThreadFun(PVOID pM)
{
WriterPrintf("写者等待写文件...\n");
//写者申请写文件
AcquireSRWLockExclusive(&g_srwLock);WriterPrintf("写者正在写文件...\n");
Sleep(rand() % 100);
WriterPrintf("写者写文件完成!\n");
ReleaseSRWLockExclusive(&g_srwLock);
return 0;
}int main()
{
printf("读者写者问题续 读写锁SRWLock\n");
printf(" -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n");InitializeCriticalSection(&g_cs);
InitializeSRWLock(&g_srwLock);HANDLE hThread[READER_NUM + 1];
int i;
for (i = 1; i <= 2; i++)
hThread[i] = (HANDLE)_beginthreadex(NULL, 0, ReaderThreadFun, NULL, 0, NULL);
hThread[0] = (HANDLE)_beginthreadex(NULL, 0, WriterThreadFun, NULL, 0, NULL);
for (; i <= READER_NUM; i++)
hThread[i] = (HANDLE)_beginthreadex(NULL, 0, ReaderThreadFun, NULL, 0, NULL);
WaitForMultipleObjects(READER_NUM + 1, hThread, TRUE, INFINITE);for (i = 0; i < READER_NUM + 1; i++)
CloseHandle(hThread[i]);DeleteCriticalSection(&g_cs);
system("pause");
return 0;
}
对比下《秒杀多线程第十一篇读者写者问题》中的代码就可以发现这份代码确实清爽许多了。这个程序用VS2008编译可以通过,但在XP系统下运行会导致报错。
在Win7系统下能够正确的运行,结果如图所示:
最后总结一下读写锁SRWLock
1.读写锁声明后要初始化,但不用销毁,系统会自动清理读写锁。
2.读取者和写入者分别调用不同的申请函数和释放函数。
转载请标明出处,原文地址:http://blog.csdn.net/morewindows/article/details/7650574
如果觉得本文对您有帮助,请点击‘顶’支持一下,您的支持是我写作最大的动力,谢谢。
读者写者问题继 读写锁SRWLock的更多相关文章
- 多线程面试题系列(14):读者写者问题继 读写锁SRWLock
在第十一篇文章中我们使用事件和一个记录读者个数的变量来解决读者写者问题.问题虽然得到了解决,但代码有点复杂.本篇将介绍一种新方法--读写锁SRWLock来解决这一问题.读写锁在对资源进行保护的同时,还 ...
- 转---秒杀多线程第十四篇 读者写者问题继 读写锁SRWLock
在<秒杀多线程第十一篇读者写者问题>文章中我们使用事件和一个记录读者个数的变量来解决读者写者问题.问题虽然得到了解决,但代码有点复杂.本篇将介绍一种新方法——读写锁SRWLock来解决这一 ...
- 秒杀多线程第十四篇 读者写者问题继 读写锁SRWLock (续)
java 包实现了读写锁的操作: package com.multithread.readwritelock; import java.util.concurrent.CountDownLatch; ...
- 多线程 读写锁SRWLock
在<秒杀多线程第十一篇读者写者问题>文章中我们使用事件和一个记录读者个数的变量来解决读者写者问题.问题虽然得到了解决,但代码有点复杂.本篇将介绍一种新方法——读写锁SRWLock来解决这一 ...
- 读写锁 SRWLOCK
读写锁在对资源进行保护的同时,还能区分想要读取资源值的线程(读取者线程)和想要更新资源的线程(写入者线程). 对于读取者线程,读写锁会允许他们并发的执行.当有写入者线程在占有资源时,读写锁会让其它写入 ...
- 最新Windows下c++读写锁SRWLock介绍
https://blog.csdn.net/MoreWindows/article/details/7650574 https://blog.csdn.net/chenzhjlf/article/de ...
- 读者写者问题(有bug 后续更改)
与上一篇<秒杀多线程第十篇 生产者消费者问题>的生产者消费者问题一样,读者写者也是一个非常著名的同步问题.读者写者问题描述非常简单,有一个写者很多读者,多个读者可以同时读文件,但写者在写文 ...
- sqlite3 读写锁
转载:https://blog.csdn.net/u012218838/article/details/79362929(sqlite3 使用读写锁SRWLOCK例子) 转载:https://my.o ...
- Linux多线程实践(6) --Posix读写锁解决读者写者问题
Posix读写锁 int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *rest ...
随机推荐
- JavaScript的事件对象_键盘事件
用户在使用键盘时会触发键盘事件.“DOM2 级事件”最初规定了键盘事件,结果又删除了相应的内容.最终还是使用最初的键盘事件,不过 IE9 已经率先支持“DOM3”级键盘事件. 一.键码 在发生 key ...
- eclipse设置字体、背景(豆绿)色、自动提示
背景色:(护眼豆绿色) window-->preferences-->General-->Editors-->Text Editors-->(最下遍一栏中的)Backgr ...
- VB6.0调用DLL
目录 第1章 VB6.0调用DLL 1 1 VC++编写DLL 1 1.1 使用__stdcall 1 1.2 使用 .DEF 文件 1 2 简单数据类型 2 2.1 传 ...
- css三级下拉的导航栏
#menu{ height: 65px; width:100%; background-color: rgba(0, 0, 0, 0.5);}#menu ul{ list-style: none;}# ...
- 20145218 《Java程序设计》第二周学习总结
Java中的注释格式 单行注释 //注释文字 多行注释 /注释文字/ 文档注释 /**注释文字*/ 注释不仅仅是对代码进行解释,在上一篇博客中也写过,注释也可以用来检查程序中的错误,可以说是一个小窍门 ...
- 企业用户选择Java多于.NET的 5个原因
.NET 和 Java 是当今社会最受欢迎的两种编程语言, 长期的发展和强大的功能使他们足以在编程界立足. 十余年的争论也没得到结果的一个话题就是——他们哪个更好一些? 今天, 我们不再去讨论JAVA ...
- jQuery 请指出'$'和'$.fn'的区别?或者说出'$.fn'的用途。
http://hi.baidu.com/chy0806css/item/acc52425099c30ff50fd87eb Jquery为开发插件提供了两个方法,分别是: $.extend(obj);$ ...
- hdu----(4686)Arc of Dream(矩阵快速幂)
Arc of Dream Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Tota ...
- hdu----(3068)最长回文(manacher)
最长回文 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- 支持向量机的smo算法(MATLAB code)
建立smo.m % function [alpha,bias] = smo(X, y, C, tol) function model = smo(X, y, C, tol) % SMO: SMO al ...