`

读者写者问题

 
阅读更多

第一   写者要等到没有读者时才能去写文件。

 

第二   所有读者要等待写者完成写文件后才能去读文件。

 

1.  对互斥量进行判断时,在进入关键段后还要在判断一次,实现双重检测。

2.  在读线程的第一个关键段中,使用旋转锁,可以避免在第二个关键段中,别的线程提前释放写者互斥量的情况。

3.  在写者中,只是做了比较简单的判断,来实现和读者的互斥运行。

 

 

#include <iostream>
#include <windows.h>
#include <process.h>

using namespace std;

const int NUM = 30, READER_SIZE = 10;
HANDLE readS;
int readThNum,total;
HANDLE thread_r[NUM], thread_o[NUM], thread_w[NUM];
CRITICAL_SECTION sc, oc;

bool readLock, writeLock, reverseLock;

// 读线程
unsigned int __stdcall read(PVOID pm) {
	// 持续循环检测writeLock状态位
	while(1) {
		if(readLock) {
			WaitForSingleObject(readS, INFINITE);

			EnterCriticalSection(&sc);
			// 再次检测
			if(!readLock) {
				cout << "reversed" << endl;
				// 使用旋转锁,来避免当readThNum为0时的重复读取
				while(reverseLock) {
					Sleep(50);
				}
			}
			total++;
			readThNum++;
			cout << GetCurrentThreadId() << "号,读进程开始..." << endl;
			LeaveCriticalSection(&sc);

			// do something...
			Sleep(rand() % 300);

			EnterCriticalSection(&sc);
			readThNum--;
			if(readThNum == 0) {
				readLock = false;
				reverseLock = true;
				writeLock = true;
			}
			cout << "    " << GetCurrentThreadId() << "号,读进程执行完毕..." << endl;
			LeaveCriticalSection(&sc);
			ReleaseSemaphore(readS, 1, NULL);
			break;
		} else {
			Sleep(50);
		}
	}
	return 0;
}

// 写线程
unsigned int __stdcall write(PVOID pm) {
	// 持续循环检测writeLock状态位
	while(1) {
		if(writeLock) {
			EnterCriticalSection(&oc);
			if(writeLock) {
				cout << GetCurrentThreadId() << "号,--------------写进程开始..." << endl;
				Sleep(100);
				cout << GetCurrentThreadId() << "号,--------------写进程执行完毕..." << endl;
				// 检测读线程是否已经执行完毕
				if(total != 2*NUM) {
					writeLock = false;
				}
				readLock = true;
				reverseLock = false;
				LeaveCriticalSection(&oc);
				break;
			} else {
				LeaveCriticalSection(&oc);
			}
		}
		Sleep(50);
	}
	return 0;
}

int main() {

	readLock = true;
	writeLock = false;
	reverseLock = false;

	readS = CreateSemaphore(NULL, READER_SIZE, READER_SIZE, NULL);
	InitializeCriticalSection(&sc);
	InitializeCriticalSection(&oc);

	int i = 0;
	for(; i<NUM; i++) {
		thread_r[i] = (HANDLE) _beginthreadex(NULL, 0, read, NULL, 0, NULL);
		thread_w[i] = (HANDLE) _beginthreadex(NULL, 0, write, NULL, 0, NULL);
	}
	
	WaitForMultipleObjects(NUM, thread_r, TRUE, INFINITE);
	Sleep(100);
	// 在执行30个 读线程
	for(i=0; i<NUM; i++) {
		thread_o[i] = (HANDLE) _beginthreadex(NULL, 0, read, NULL, 0, NULL);
	}
//	writeLock = true;
	WaitForMultipleObjects(NUM, thread_w, TRUE, INFINITE);
	WaitForMultipleObjects(NUM, thread_o, TRUE, INFINITE);

	DeleteCriticalSection(&sc);
	DeleteCriticalSection(&oc);

	CloseHandle(readS);

	cout << "运行完毕" << endl;

	getchar();
	return 0;
}

运行效果如下:

 






  • 大小: 46.4 KB
  • 大小: 30.1 KB
  • 大小: 29.1 KB
0
0
分享到:
评论
2 楼 J2EE大鸟 2013-11-26  
lvwenwen 写道
c++的发这里来

用了几年java之后,发现c++还是有必要学习的,就弄在一起了。
1 楼 lvwenwen 2013-11-26  
c++的发这里来

相关推荐

Global site tag (gtag.js) - Google Analytics