700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 秒杀多线程第十四篇 读者写者问题继 读写锁SRWLock

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

时间:2023-09-27 20:02:04

相关推荐

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

在《秒杀多线程第十一篇读者写者问题》文章中我们使用事件和一个记录读者个数的变量来解决读者写者问题。问题虽然得到了解决,但代码有点复杂。本篇将介绍一种新方法——读写锁SRWLock来解决这一问题。读写锁在对资源进行保护的同时,还能区分想要读取资源值的线程(读取者线程)和想要更新资源的线程(写入者线程)。对于读取者线程,读写锁会允许他们并发的执行。当有写入者线程在占有资源时,读写锁会让其它写入者线程和读取者线程等待。因此用读写锁来解决读者写者问题会使代码非常清晰和简洁。

下面就来看看如何使用读写锁,要注意编译读写锁程序需要VS,运行读写锁程序要在Vista或Windows Server系统(比这两个更高级的系统也可以)。读写锁的主要函数就五个,分为初始化函数,写入者线程申请和释放函数,读取者线程申请和释放函数,以下是详细的函数使用说明:

第一个InitializeSRWLock

函数功能:初始化读写锁

函数原型:VOIDInitializeSRWLock(PSRWLOCKSRWLock);

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

第二个AcquireSRWLockExclusive

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

函数原型:VOIDAcquireSRWLockExclusive(PSRWLOCKSRWLock);

第三个ReleaseSRWLockExclusive

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

函数原型:VOIDReleaseSRWLockExclusive(PSRWLOCKSRWLock);

第四个AcquireSRWLockShared

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

函数原型:VOIDAcquireSRWLockShared(PSRWLOCKSRWLock);

第五个ReleaseSRWLockShared

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

函数原型:VOIDReleaseSRWLockShared(PSRWLOCKSRWLock);

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

使用读写锁精简后的代码如下(代码中变参函数的实现请参阅《C,C++中使用可变参数》,控制台颜色设置请参阅《VC 控制台颜色设置》):

[cpp]view plaincopy//读者与写者问题继读写锁SRWLock #include<stdio.h> #include<process.h> #include<windows.h> //设置控制台输出颜色 BOOLSetConsoleColor(WORDwAttributes) { HANDLEhConsole=GetStdHandle(STD_OUTPUT_HANDLE); if(hConsole==INVALID_HANDLE_VALUE) returnFALSE; returnSetConsoleTextAttribute(hConsole,wAttributes); } constintREADER_NUM=5;//读者个数 //关键段和事件 CRITICAL_SECTIONg_cs; SRWLOCKg_srwLock; //读者线程输出函数(变参函数的实现) voidReaderPrintf(char*pszFormat,...) { va_listpArgList; va_start(pArgList,pszFormat); EnterCriticalSection(&g_cs); vfprintf(stdout,pszFormat,pArgList); LeaveCriticalSection(&g_cs); va_end(pArgList); } //读者线程函数 unsignedint__stdcallReaderThreadFun(PVOIDpM) { ReaderPrintf("编号为%d的读者进入等待中...\n",GetCurrentThreadId()); //读者申请读取文件 AcquireSRWLockShared(&g_srwLock); //读取文件 ReaderPrintf("编号为%d的读者开始读取文件...\n",GetCurrentThreadId()); Sleep(rand()%100); ReaderPrintf("编号为%d的读者结束读取文件\n",GetCurrentThreadId()); //读者结束读取文件 ReleaseSRWLockShared(&g_srwLock); return0; } //写者线程输出函数 voidWriterPrintf(char*pszStr) { EnterCriticalSection(&g_cs); SetConsoleColor(FOREGROUND_GREEN); printf("%s\n",pszStr); SetConsoleColor(FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE); LeaveCriticalSection(&g_cs); } //写者线程函数 unsignedint__stdcallWriterThreadFun(PVOIDpM) { WriterPrintf("写者线程进入等待中..."); //写者申请写文件 AcquireSRWLockExclusive(&g_srwLock); //写文件 WriterPrintf("写者开始写文件....."); Sleep(rand()%100); WriterPrintf("写者结束写文件"); //标记写者结束写文件 ReleaseSRWLockExclusive(&g_srwLock); return0; } intmain() { printf("读者写者问题继读写锁SRWLock\n"); printf("--byMoreWindows(/MoreWindows)--\n\n"); //初始化读写锁和关键段 InitializeCriticalSection(&g_cs); InitializeSRWLock(&g_srwLock); HANDLEhThread[READER_NUM+1]; inti; //先启动二个读者线程 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); Sleep(50); //最后启动其它读者结程 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); return0; }

对比下《秒杀多线程第十一篇读者写者问题》中的代码就可以发现这份代码确实清爽许多了。这个程序用VS编译可以通过,但在XP系统下运行会导致报错。

在Win7系统下能够正确的运行,结果如图所示:

最后总结一下读写锁SRWLock

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

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

转载请标明出处,原文地址:/morewindows/article/details/7650574

如果觉得本文对您有帮助,请点击‘顶’支持一下,您的支持是我写作最大的动力,谢谢。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。