描述:有一个写者很多读者,多个读者可以同时读文件,但写者在写文件时不允许有读者在读文件,同样有读者在读文件时写者也不去能写文件。
解决方案之一:使用信号量。
处于等待的情况有以下几种:
第一.写者要等到没有读者时才能去写文件。
第二.所有读者要等待写者完成写文件后才能去读文件。
描述代码:
int readcount;
semphore Mutex,rcMutex;
void reader() {
while(true) {
semWait(rcMutex);
readcount++;
if(readcount == 1) {
semWait(Mutex);
}
semSignal(rcMutex);
READ();
semWait(rcMutex);
readcount--;
if(readcount == 0) {
semSignal(Mutex);
}
semSignal(rcMutex);
}
}
void writer() {
while(true) {
semWait(Mutex);
WRITE();
semSignal(Mutex);
}
}
void main() {
readcount = 0;
parBegin(reader,writer);
}
实现代码:
/// 读者写者问题(读者优先)
#include <windows.h>
#include <iostream>
unsigned short readID; ///读操作的进程号
unsigned short writeID; ///写操作的进程号
HANDLE rcMutex = NULL;///用于对readCount的互斥访问
HANDLE Mutex = NULL;///用于对临界区的互斥访问
int readCount = 0;///读者数量
bool p_ccontinue = true; ///控制程序结束
///读操作
void read() {
readID = GetCurrentThreadId();
std::cout << "Reading " << readID << " ... ";
std::cout << "Succeed" << std::endl;
}
///写操作
void write() {
writeID = GetCurrentThreadId();
std::cout << "Writing " << writeID << " ... ";
std::cout << "Succeed" << std::endl;
}
///读者
DWORD WINAPI Reader(LPVOID lpPara) {
while (true) {
WaitForSingleObject(rcMutex, INFINITE);///P(rcMutex)
readCount++;
if (readCount == 1) {
///如果是第一个读者,那么限制写者的访问
std::cout<<"\n\t第一个读者\n";
WaitForSingleObject(Mutex, INFINITE);/// P(Mutex)
}
ReleaseMutex(rcMutex);/// V(rcMutex)
read();
Sleep(1500);
WaitForSingleObject(rcMutex, INFINITE);/// P(rcMutex)
readCount--;
if (readCount == 0) {
///如果是最后一个读者,那么释放以供写者或读者访问
std::cout<<"\t最后一个读者\n";
ReleaseMutex(Mutex);/// V(Mutex)
}
ReleaseMutex(rcMutex);/// V(rcMutex)
}
}
///写者
DWORD WINAPI Writer(LPVOID lpPara) {
while (true) {
WaitForSingleObject(Mutex, INFINITE);/// P(Mutex)
write();
Sleep(1500);
ReleaseMutex(Mutex);/// V(Mutex)
}
}
int main() {
/// 创建互斥信号量
rcMutex = CreateMutex(NULL, false, NULL);
Mutex = CreateMutex(NULL, false, NULL);
const unsigned short READERS_COUNT = 2; ///读者的个数
const unsigned short WRITERS_COUNT = 2; ///写者的个数
const unsigned short THREADS_COUNT = READERS_COUNT+WRITERS_COUNT; ///总的线程数
HANDLE hThreads[THREADS_COUNT]; ///各线程的 handle
DWORD readerID[READERS_COUNT];
DWORD writerID[WRITERS_COUNT];
///创建读者线程
for (int i = 0; i < READERS_COUNT; i++) {
hThreads[i] = CreateThread(NULL, 0, Reader, NULL, 0, &readerID[i]);
if (hThreads[i]==NULL)
return -1;
}
///创建写者线程
for (int i = 0; i < WRITERS_COUNT; i++) {
hThreads[READERS_COUNT+i] = CreateThread(NULL, 0, Writer, NULL, 0, &writerID[i]);
if (hThreads[i]==NULL)
return -1;
}
while(p_ccontinue) {
if(getchar()) { ///按回车后终止程序运行
p_ccontinue = false;
}
}
return 0;
}
部分参考:https://blog.csdn.net/morewindows/article/details/7596034