读写者问题
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; }