秒殺多線程第十四篇 讀者寫者問題繼 讀寫鎖SRWLock

來源:互聯網
上載者:User

    在《秒殺多線程第十一篇讀者寫者問題》文章中我們使用事件和一個記錄讀者個數的變數來解決讀者寫者問題。問題雖然得到瞭解決,但代碼有點複雜。本篇將介紹一種新方法——讀寫鎖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 控制台顏色設定》):

//讀者與寫者問題繼 讀寫鎖SRWLock#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", GetCurrentThreadId());//讀者申請讀取檔案AcquireSRWLockShared(&g_srwLock);//讀取檔案ReaderPrintf("編號為%d的讀者開始讀取檔案...\n", GetCurrentThreadId());Sleep(rand() % 100);ReaderPrintf(" 編號為%d的讀者結束讀取檔案\n", GetCurrentThreadId());//讀者結束讀取檔案ReleaseSRWLockShared(&g_srwLock);return 0;}//寫者線程輸出函數void WriterPrintf(char *pszStr){EnterCriticalSection(&g_cs);SetConsoleColor(FOREGROUND_GREEN);printf("     %s\n", pszStr);SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);LeaveCriticalSection(&g_cs);}//寫者線程函數unsigned int __stdcall WriterThreadFun(PVOID pM){WriterPrintf("寫者線程進入等待中...");//寫者申請寫檔案AcquireSRWLockExclusive(&g_srwLock);//寫檔案WriterPrintf("  寫者開始寫檔案.....");Sleep(rand() % 100);WriterPrintf("  寫者結束寫檔案");//標記寫者結束寫檔案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);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);return 0;}

對比下《秒殺多線程第十一篇讀者寫者問題》中的代碼就可以發現這份代碼確實清爽許多了。這個程式用VS2008編譯可以通過,但在XP系統下運行會導致報錯。

在Win7系統下能夠正確的運行,結果:

 

 

最後總結一下讀寫鎖SRWLock

1.讀寫鎖聲明後要初始化,但不用銷毀,系統會自動清理讀寫鎖。

2.讀取者和寫入者分別調用不同的申請函數和釋放函數。

 

 

轉載請標明出處,原文地址:http://blog.csdn.net/morewindows/article/details/7650574

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

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.