1. 程式人生 > >多程序之讀寫併發問題

多程序之讀寫併發問題

// 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);
}

這個過程就是在第一個讀者在讀取的時候,我們需要進行寫的設定,告訴寫程序,現在不要進行寫操作,而在最後一個讀者讀取的時候恢復,告訴寫程序現在可以進行寫操作了

同時寫程序操作的時候也要告訴讀程序現在不要讀了,我正在寫,而對記錄讀者個數的全域性變數進行操作的時候,我們要記住必須是原子操作,也即這段程式碼的執行必須同時只有一個執行緒才可以