多程序之讀寫併發問題
阿新 • • 發佈:2019-02-11
// Reader_Writer.cpp : 定義控制檯應用程式的入口點。 // #include "stdafx.h" #include<iostream> #include<Windows.h> #include<process.h> using namespace std; HANDLE gEventNoReader=0,gEventWriting=0; int gReaderCount=0; const int READER_NUM = 5; //讀者個數 CRITICAL_SECTION g_cs; DWORD ReadFunc(LPVOID) { //在讀者數量不是1的情況下不需要等待,但是呢又指定 程式碼只能同時又一個執行緒執行 所以在gReaderCount不是 1 的情況下其他執行緒進不來這段程式碼 ::EnterCriticalSection(&g_cs); gReaderCount++; if(gReaderCount==1) { //第一個讀者讀檔案的時候做標記,不允許寫檔案 //開始等待事件 ::WaitForSingleObject(gEventWriting,INFINITE); cout<<"第一個讀者開始讀取\n"; ::ResetEvent(gEventWriting); } ::LeaveCriticalSection(&g_cs); cout<<"讀者正在讀檔案\n"; //::Sleep(100); ::EnterCriticalSection(&g_cs); gReaderCount--; if(gReaderCount==0) { //最後一個讀者負責做標記告訴寫程序沒有讀者了,可以寫檔案了 cout<<"最後一個讀者讀取: "; ::SetEvent(gEventNoReader); } ::LeaveCriticalSection(&g_cs); cout<<"讀者結束等待讀取檔案\n"; return 0; } DWORD WriteFun(LPVOID lp) { ::WaitForSingleObject(gEventNoReader,INFINITE); //通知讀者不可以讀檔案了 ::ResetEvent(gEventWriting); cout<<"開始進行寫檔案\n"; cout<<"寫檔案結束\n"; ::SetEvent(gEventWriting); return 0; } int main() { gEventNoReader=::CreateEvent(NULL,FALSE,TRUE,NULL); gEventWriting=::CreateEvent(NULL,true,true,NULL); ::InitializeCriticalSection(&g_cs); //先啟動兩個讀者程序 HANDLE hThread[READER_NUM+1]={0}; int i=0; DWORD TMP=0; for(i=1;i<2;i++) { hThread[i]=::CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ReadFunc,NULL,0,&TMP); } //開啟寫執行緒 hThread[0]=::CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)WriteFun,NULL,0,&TMP); for ( ; i <= READER_NUM; i++) hThread[i] =CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ReadFunc,NULL,0,&TMP); WaitForMultipleObjects(READER_NUM + 1, hThread, TRUE, INFINITE); for (i = 0; i < READER_NUM + 1; i++) CloseHandle(hThread[i]); CloseHandle(gEventNoReader); CloseHandle(gEventWriting); ::DeleteCriticalSection(&g_cs); }
這個過程就是在第一個讀者在讀取的時候,我們需要進行寫的設定,告訴寫程序,現在不要進行寫操作,而在最後一個讀者讀取的時候恢復,告訴寫程序現在可以進行寫操作了
同時寫程序操作的時候也要告訴讀程序現在不要讀了,我正在寫,而對記錄讀者個數的全域性變數進行操作的時候,我們要記住必須是原子操作,也即這段程式碼的執行必須同時只有一個執行緒才可以