日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時間:2024/4/11 编程问答 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 秒杀多线程第十四篇 读者写者问题继 读写锁SRWLock 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在《秒殺多線程第十一篇讀者寫者問題》文章中我們使用事件和一個記錄讀者個數(shù)的變量來解決讀者寫者問題。問題雖然得到了解決,但代碼有點復(fù)雜。本篇將介紹一種新方法——讀寫鎖SRWLock來解決這一問題。讀寫鎖在對資源進行保護的同時,還能區(qū)分想要讀取資源值的線程(讀取者線程)和想要更新資源的線程(寫入者線程)。對于讀取者線程,讀寫鎖會允許他們并發(fā)的執(zhí)行。當(dāng)有寫入者線程在占有資源時,讀寫鎖會讓其它寫入者線程和讀取者線程等待。因此用讀寫鎖來解決讀者寫者問題會使代碼非常清晰和簡潔。

?

??? 下面就來看看如何使用讀寫鎖,要注意編譯讀寫鎖程序需要VS2008,運行讀寫鎖程序要在VistaWindows Server2008系統(tǒng)(比這兩個更高級的系統(tǒng)也可以)。讀寫鎖的主要函數(shù)就五個,分為初始化函數(shù),寫入者線程申請和釋放函數(shù),讀取者線程申請和釋放函數(shù),以下是詳細(xì)的函數(shù)使用說明:

第一個?InitializeSRWLock

函數(shù)功能:初始化讀寫鎖

函數(shù)原型:VOID?InitializeSRWLock(PSRWLOCK?SRWLock);

函數(shù)說明:初始化(沒有刪除或銷毀SRWLOCK的函數(shù),系統(tǒng)會自動清理)

?

第二個?AcquireSRWLockExclusive

函數(shù)功能:寫入者線程申請寫資源。

函數(shù)原型:VOID?AcquireSRWLockExclusive(PSRWLOCK?SRWLock);

?

第三個?ReleaseSRWLockExclusive

函數(shù)功能:寫入者線程寫資源完畢,釋放對資源的占用。

函數(shù)原型:VOID?ReleaseSRWLockExclusive(PSRWLOCK?SRWLock);

?

第四個?AcquireSRWLockShared

函數(shù)功能:讀取者線程申請讀資源。

函數(shù)原型:VOID?AcquireSRWLockShared(PSRWLOCK?SRWLock);

?

第五個?ReleaseSRWLockShared

函數(shù)功能:讀取者線程結(jié)束讀取資源,釋放對資源的占用。

函數(shù)原型:VOID?ReleaseSRWLockShared(PSRWLOCK?SRWLock);

?

注意一個線程僅能鎖定資源一次,不能多次鎖定資源。

?

使用讀寫鎖精簡后的代碼如下(代碼中變參函數(shù)的實現(xiàn)請參閱《C,C++中使用可變參數(shù)》,控制臺顏色設(shè)置請參閱《VC 控制臺顏色設(shè)置》):

[cpp]?view plaincopy
  • //讀者與寫者問題繼?讀寫鎖SRWLock??
  • #include?<stdio.h>??
  • #include?<process.h>??
  • #include?<windows.h>??
  • //設(shè)置控制臺輸出顏色??
  • 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;??//讀者個數(shù)??
  • //關(guān)鍵段和事件??
  • CRITICAL_SECTION?g_cs;??
  • SRWLOCK??????????g_srwLock;???
  • //讀者線程輸出函數(shù)(變參函數(shù)的實現(xiàn))??
  • void?ReaderPrintf(char?*pszFormat,?...)??
  • {??
  • ????va_list???pArgList;??
  • ????va_start(pArgList,?pszFormat);??
  • ????EnterCriticalSection(&g_cs);??
  • ????vfprintf(stdout,?pszFormat,?pArgList);??
  • ????LeaveCriticalSection(&g_cs);??
  • ????va_end(pArgList);??
  • }??
  • //讀者線程函數(shù)??
  • unsigned?int?__stdcall?ReaderThreadFun(PVOID?pM)??
  • {??
  • ????ReaderPrintf("?????編號為%d的讀者進入等待中...\n",?GetCurrentThreadId());??
  • ????//讀者申請讀取文件??
  • ????AcquireSRWLockShared(&g_srwLock);??
  • ??
  • ????//讀取文件??
  • ????ReaderPrintf("編號為%d的讀者開始讀取文件...\n",?GetCurrentThreadId());??
  • ????Sleep(rand()?%?100);??
  • ????ReaderPrintf("?編號為%d的讀者結(jié)束讀取文件\n",?GetCurrentThreadId());??
  • ??
  • ????//讀者結(jié)束讀取文件??
  • ????ReleaseSRWLockShared(&g_srwLock);??
  • ????return?0;??
  • }??
  • //寫者線程輸出函數(shù)??
  • void?WriterPrintf(char?*pszStr)??
  • {??
  • ????EnterCriticalSection(&g_cs);??
  • ????SetConsoleColor(FOREGROUND_GREEN);??
  • ????printf("?????%s\n",?pszStr);??
  • ????SetConsoleColor(FOREGROUND_RED?|?FOREGROUND_GREEN?|?FOREGROUND_BLUE);??
  • ????LeaveCriticalSection(&g_cs);??
  • }??
  • //寫者線程函數(shù)??
  • unsigned?int?__stdcall?WriterThreadFun(PVOID?pM)??
  • {??
  • ????WriterPrintf("寫者線程進入等待中...");??
  • ????//寫者申請寫文件??
  • ????AcquireSRWLockExclusive(&g_srwLock);??
  • ??????????
  • ????//寫文件??
  • ????WriterPrintf("??寫者開始寫文件.....");??
  • ????Sleep(rand()?%?100);??
  • ????WriterPrintf("??寫者結(jié)束寫文件");??
  • ??
  • ????//標(biāo)記寫者結(jié)束寫文件??
  • ????ReleaseSRWLockExclusive(&g_srwLock);??
  • ????return?0;??
  • }??
  • int?main()??
  • {??
  • ????printf("??讀者寫者問題繼?讀寫鎖SRWLock\n");??
  • ????printf("?--?by?MoreWindows(?http://blog.csdn.net/MoreWindows?)?--\n\n");??
  • ??
  • ????//初始化讀寫鎖和關(guā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);??
  • ????Sleep(50);??
  • ????//最后啟動其它讀者結(jié)程??
  • ????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]);??
  • ??
  • ????//銷毀關(guān)鍵段??
  • ????DeleteCriticalSection(&g_cs);??
  • ????return?0;??
  • }??
  • 對比下《秒殺多線程第十一篇讀者寫者問題》中的代碼就可以發(fā)現(xiàn)這份代碼確實清爽許多了。這個程序用VS2008編譯可以通過,但在XP系統(tǒng)下運行會導(dǎo)致報錯。

    Win7系統(tǒng)下能夠正確的運行,結(jié)果如圖所示:

    ?

    ?

    最后總結(jié)一下讀寫鎖SRWLock

    1.讀寫鎖聲明后要初始化,但不用銷毀,系統(tǒng)會自動清理讀寫鎖。

    2.讀取者和寫入者分別調(diào)用不同的申請函數(shù)和釋放函數(shù)。

    ?

    ?

    轉(zhuǎn)載請標(biāo)明出處,原文地址:http://blog.csdn.net/morewindows/article/details/7650574

    如果覺得本文對您有幫助,請點擊支持一下,您的支持是我寫作最大的動力,謝謝。


    總結(jié)

    以上是生活随笔為你收集整理的秒杀多线程第十四篇 读者写者问题继 读写锁SRWLock的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。