读写者问题
C++代码实现
#include <iostream>
#include <windows.h>
#include <fstream>
#define MAX_THREAD_NUM 64 //最大线程数
#define INTE_PER_SEC 1000 //每秒时钟中断的数目
#define MAX_FILE_NUM 32 //最大文件数目数
#define MAX_STR_LEN 32 //字符串的长度
using namespace std;
int readcount = 0; //读者数目
int writecount = 0; //写者数目
CRITICAL_SECTION RP_Write; //临界资源
CRITICAL_SECTION cs_Write;
CRITICAL_SECTION cs_Read;
struct ThreadInfo {
int serial; //线程序号
char entity; //线程类别(判断是读者还是写者线程)
double delay; //线程延迟时间
double persist; //线程读写操作时间
};
//读者优先<--->读者线程//
void RP_ReaderThread(void *p) //P:读者线程信息
{
//互斥变量
HANDLE h_Mutex;
h_Mutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "mutex_for_readcount");
DWORD wait_for_mutex; //等待互斥变量所有权
DWORD m_delay; //延迟时间
DWORD m_persist; //读文件持续时间
int m_serial; //线程序号
// 从参数中获得信息
m_serial = ((ThreadInfo *) (p))->serial;
m_delay = (DWORD) (((ThreadInfo *) (p))->delay * INTE_PER_SEC);
m_persist = (DWORD) (((ThreadInfo *) (p))->persist * INTE_PER_SEC);
Sleep(m_delay); //延迟等待
cout << "Reader thread " << m_serial << " sents the reading require !" << endl;
//等待互斥信号,保证对 ReadCount 的访问,修改互斥
wait_for_mutex = WaitForSingleObject(h_Mutex, -1);
//读者数目增加
readcount++;
if (readcount == 1) {
//第一个读者,等待资源
EnterCriticalSection(&RP_Write);
}
ReleaseMutex(h_Mutex); //释放互斥信
//读文件
cout << "Reader thread " << m_serial << " begins to read file !" << endl;
Sleep(m_persist);
//退出线程
cout << "Reader thread " << m_serial << " finished reading file !" << endl;
//等待互斥信号,保证对 ReadCount 的访问,修改互斥
wait_for_mutex = WaitForSingleObject(h_Mutex, -1);
//读者数目减少
readcount--;
if (readcount == 0) {
//如果所有的读者读完,唤醒写者
LeaveCriticalSection(&RP_Write);
}
ReleaseMutex(h_Mutex); //释放互斥信号
}
//P:写者线程信息
void RP_WriterThread(void *p) {
DWORD m_delay; //延迟时间
DWORD m_persist; //写文件持续时间
int m_serial; //线程序号
// 从参数中获得信息
m_serial = ((ThreadInfo *) (p))->serial;
m_delay = (DWORD) (((ThreadInfo *) (p))->delay * INTE_PER_SEC);
m_persist = (DWORD) (((ThreadInfo *) (p))->persist * INTE_PER_SEC);
Sleep(m_delay);
cout << "Writer thread " << m_serial << " sents the writing require !" << endl;
//等待资源
EnterCriticalSection(&RP_Write);
//写文件
cout << "Writer thread " << m_serial << " begins to write file !" << endl;
Sleep(m_persist);
//退出线程
cout << "Writer thread " << m_serial << " finished writing file !" << endl;
//释放资源
LeaveCriticalSection(&RP_Write);
}
//读者优先处理函数
void ReaderPriority(const char *fileName) {
DWORD n_thread = 0; //线程数目
DWORD thread_ID; //线程 ID
DWORD wait_for_all; //等待所有线程结束
//互斥对象
HANDLE h_Mutex;
h_Mutex = CreateMutex(NULL, FALSE, "mutex_for_readcount");
//线程对象的数组
HANDLE h_Thread[MAX_THREAD_NUM];
ThreadInfo thread_info[MAX_THREAD_NUM];
readcount = 0; //初始化 readcount
InitializeCriticalSection(&RP_Write); //初始化临界区
ifstream inFile;
inFile.open(fileName);
if (!inFile) {
cout << "文件打开失败!" << endl;
}
cout << "读者优先:" << endl;
while (inFile) {
//读入每一个读者,写者的信息
inFile >> thread_info[n_thread].serial;
inFile >> thread_info[n_thread].entity;
inFile >> thread_info[n_thread].delay;
inFile >> thread_info[n_thread++].persist;
inFile.get();
}
for (int i = 0; i < (int) (n_thread); i++) {
if (thread_info[i].entity == 'R') {
//创建读者进程
h_Thread[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) (RP_ReaderThread), &thread_info[i], 0,
&thread_ID);
} else {
//创建写线程
h_Thread[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) (RP_WriterThread), &thread_info[i], 0,
&thread_ID);
}
}
//等待所有的线程结束
wait_for_all = WaitForMultipleObjects(n_thread, h_Thread, TRUE, -1);
cout << "All reader and writer have finished operating !" << endl;
}
//写者优先---读者线程
//P:读者线程信息
void WP_ReaderThread(void *p) {
HANDLE print;
print = CreateMutex(NULL, FALSE, LPCTSTR("mutex_for_print"));
//互斥变量
HANDLE h_Mutex1;
h_Mutex1 = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "mutex1");
HANDLE h_Mutex2;
h_Mutex2 = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "mutex2");
DWORD wait_for_mutex1; //等待互斥变量所有权
DWORD wait_for_mutex2;
DWORD m_delay; //延迟时间
DWORD m_persist; //读文件持续时间
int m_serial; //线程的序号
//从参数中得到信息
m_serial = ((ThreadInfo *) (p))->serial;
m_delay = (DWORD) (((ThreadInfo *) (p))->delay * INTE_PER_SEC);
m_persist = (DWORD) (((ThreadInfo *) (p))->persist * INTE_PER_SEC);
Sleep(m_delay); //延迟等待
DWORD wait_to_print = WaitForSingleObject(print, -1);
cout << "Reader thread " << m_serial << " sents the reading require !" << endl;
ReleaseMutex(print);
wait_for_mutex1 = WaitForSingleObject(h_Mutex1, -1);
//读者进去临界区
EnterCriticalSection(&cs_Read);
//阻塞互斥对象 Mutex2,保证对 readCount 的访问和修改互斥
wait_for_mutex2 = WaitForSingleObject(h_Mutex2, -1);
//修改读者的数目
readcount++;
if (readcount == 1) {
// 如果是第 1 个读者,等待写者写完
EnterCriticalSection(&cs_Write);
}
ReleaseMutex(h_Mutex2);// 释放互斥信号 Mutex2
//让其他读者进去临界区
LeaveCriticalSection(&cs_Read);
ReleaseMutex(h_Mutex1);
//读文件
wait_to_print = WaitForSingleObject(print, -1);
cout << "Reader thread " << m_serial << " begins to read file !" << endl;
ReleaseMutex(print);
Sleep(m_persist);
//退出线程
wait_to_print = WaitForSingleObject(print, -1);
cout << "Reader thread " << m_serial << " finished reading file !" << endl;
ReleaseMutex(print);
//阻塞互斥对象 Mutex2,保证对 readcount 的访问,修改互斥
wait_for_mutex1 = WaitForSingleObject(h_Mutex2, -1);
readcount--;
if (readcount == 0) {
//最后一个读者,唤醒写者
LeaveCriticalSection(&cs_Write);
}
ReleaseMutex(h_Mutex2); //释放互斥信号
}
//写者优先---写者线程
//P:写者线程信息
void WP_WriterThread(void *p) {
DWORD wait_for_mutex3; //互斥变量
DWORD m_delay; //延迟时间
DWORD m_persist; //读文件持续时间
int m_serial; //线程序号
HANDLE h_Mutex3;
h_Mutex3 = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "mutex3");
//从参数中获得信息
m_serial = ((ThreadInfo *) (p))->serial;
m_delay = (DWORD) (((ThreadInfo *) (p))->delay * INTE_PER_SEC);
m_persist = (DWORD) (((ThreadInfo *) (p))->persist * INTE_PER_SEC);
Sleep(m_delay); //延迟等待
cout << "Writer thread " << m_serial << " sents the writing require !" << endl;
wait_for_mutex3 = WaitForSingleObject(h_Mutex3, -1);
writecount++; //修改写者数目
if (writecount == 1) {
EnterCriticalSection(&cs_Read);
}
ReleaseMutex(h_Mutex3);
EnterCriticalSection(&cs_Write);
cout << "Writer thread " << m_serial << " begins to write file !" << endl;
Sleep(m_persist);
cout << "Writer thread " << m_serial << " finished writing file !" << endl;
LeaveCriticalSection(&cs_Write);
wait_for_mutex3 = WaitForSingleObject(h_Mutex3, -1);
writecount--;
if (writecount == 0) {
LeaveCriticalSection(&cs_Read);
}
ReleaseMutex(h_Mutex3);
}
//写者优先处理函数
// fileName:文件名
void WriterPriority(const char *fileName) {
DWORD n_thread = 0;
DWORD thread_ID;
DWORD wait_for_all;
HANDLE h_Mutex1;
h_Mutex1 = CreateMutex(NULL, FALSE, "mutex1");
HANDLE h_Mutex2;
h_Mutex2 = CreateMutex(NULL, FALSE, "mutex2");
HANDLE h_Mutex3;
h_Mutex3 = CreateMutex(NULL, FALSE, "mutex3");
HANDLE h_Thread[MAX_THREAD_NUM];
ThreadInfo thread_info[MAX_THREAD_NUM];
readcount = 0;
writecount = 0;
InitializeCriticalSection(&cs_Write);
InitializeCriticalSection(&cs_Read);
ifstream inFile;
inFile.open(fileName);
cout << "Writer Priority:" << endl;
while (inFile) {
inFile >> thread_info[n_thread].serial;
inFile >> thread_info[n_thread].entity;
inFile >> thread_info[n_thread].delay;
inFile >> thread_info[n_thread++].persist;
inFile.get();
}
for (int i = 0; i < (int) (n_thread); i++) {
if (thread_info[i].entity == 'R') {
//创建读者进程
h_Thread[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) (WP_ReaderThread), &thread_info[i], 0,
&thread_ID);
} else if (thread_info[i].entity == 'W') {
//创建写线程
h_Thread[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) (WP_WriterThread), &thread_info[i], 0,
&thread_ID);
}
}
//等待所有的线程结束
wait_for_all = WaitForMultipleObjects(n_thread, h_Thread, TRUE, -1);
cout << "All reader and writer have finished operating !" << endl;
}
//主函数
int main() {
const char *file = "F:\\Study\\C++\\OS\\WR_EXP\\data.txt";
char ch;
cout<<endl;
while (1) {
cout << "--读者与写者问题--" << endl;
cout << "---------------" << endl;
cout << "| 1、读者优先 |" << endl;
cout << "| 2、写者优先 |" << endl;
cout << "| 3、退出 |" << endl;
cout << "---------------" << endl;
printf("请选择(1,2,3): ");
do {
ch = (char) getchar();
} while (ch != '1' && ch != '2' && ch != '3');
system("cls"); //执行清屏幕命令
switch (ch) {
case '1':
ReaderPriority(file);
break;
case '2':
WriterPriority(file);
break;
case '3':
return 0;
}
cout << endl << "按任意键继续..." << endl;
getchar();
system("cls");
}
return 0;
}