河北科技大学操作系统课程设计——读者写者问题
#include <windows.h>
#include <conio.h>
#include <stdlib.h>
#include <fstream>
#include <io.h>
#include <string.h>
#include <stdio.h>
using namespace std;
#define READER 'R'
#define WRITER 'W'
#define MAX_THREAD_NUM 32
CRITICAL_SECTION RP_Write;
CRITICAL_SECTION pright;
CRITICAL_SECTION w_Mutex;
CRITICAL_SECTION cs;
#define INTE_PER_SEC 100
int flag;
int readcount=0;
int writecount=0;
struct ThreadInfo
{ int serial;
char entity;
double delay;
double persist;
};
ThreadInfo thread_info[MAX_THREAD_NUM];
void ReaderPriority(int num);
void RP_ReaderThread(void *p);
void RP_WriterThread(void *p);
void WriterPriority(int num);
void WP_ReaderThread(void *p);
void WP_WriterThread(void *p);
void showInput(void);
void showWhich(void);
int main()
{
InitializeCriticalSection(&cs);
int num;
int choice;
while(1){
system("cls");
showInput();
scanf("%d",&choice);
switch(choice){
case 1:
system("cls");
showWhich();
break;
case 2:
exit(1);
break;
default :
printf("输入有误,请重新输入!\n");
Sleep(1000);
break;
}
}
system("pause");
return 0;
}
void showInput(void)
{
printf(" *********请选择功能*********\n");
printf(" * *\n");
printf(" * 1:模拟读者写者问题 *\n");
printf(" * *\n");
printf(" * 2:退出系统 *\n");
printf(" * *\n");
printf(" ****************************\n");
}
void show()
{
printf(" *********请选择功能*********\n");
printf(" * *\n");
printf(" * 1:读者优先 *\n");
printf(" * 2:写者优先 *\n");
printf(" * 3:返回上一级 *\n");
printf(" * 4:清屏并继续 *\n");
printf(" * 5:退出系统 *\n");
printf(" * *\n");
printf(" ****************************\n");
}
void showWhich(void)
{
int num;
int choice;
printf("请输入总的读者写者线程数:(<=32)\n");
scanf("%d",&num);
for(int i=0;i<num;i++){
printf("请输入*线程号*线程类别(R/W)*线程开始时间*线程持续时间:\n");
scanf("%d %c %lf %lf",&thread_info[i].serial,&thread_info[i].entity,&thread_info[i].delay,&thread_info[i].persist);
}
system("cls");
show();
while(1){
scanf("%d",&choice);
switch(choice){
case 1:
printf("序号 读者或写者 开始时间 持续时间\n");
for(int i=0;i<num;i++)
{ printf(" %d %c %f %f \n",
thread_info[i].serial,thread_info[i].entity,thread_info[i].delay,thread_info[i].persist);
}
ReaderPriority(num);
continue;
case 2:
printf("序号 读者或写者 开始时间 持续时间\n");
for(int i=0;i<num;i++)
{ printf(" %d %c %f %f \n",
thread_info[i].serial,thread_info[i].entity,thread_info[i].delay,thread_info[i].persist);
}
WriterPriority(num);
continue;
case 3:
flag=1;
break;
case 4:
system("cls");
show();
continue;
case 5:
flag=0;
break;
default:
printf("输入有误,请重新输入!\n");
Sleep(1000);
system("cls");
show();
continue;
};
if(flag==1) break;
if(flag==0) exit(1);
}
}
void ReaderPriority(int num)
{
DWORD n_thread=num;
DWORD thread_ID;
DWORD wait_for_all;
HANDLE rmutex;
rmutex=CreateMutex(NULL,FALSE,"mutex_for_readcount");
HANDLE h_Thread[MAX_THREAD_NUM];
readcount=0;
InitializeCriticalSection(&RP_Write);
printf("读者优先:(纵坐标为执行顺序)\n");
for (int i=0;i<(int)(n_thread);i++)
{
if (thread_info[i].entity==READER || 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);
printf("所有操作完成\n\n");
}
void RP_ReaderThread(void *p)
{
int m_ID;
DWORD m_delay;
DWORD m_persist;
m_ID=((ThreadInfo *)(p))->serial;
m_delay=(DWORD)(((ThreadInfo *)(p))->delay*INTE_PER_SEC);
m_persist=(DWORD)(((ThreadInfo *)(p))->persist*INTE_PER_SEC);
HANDLE rmutex;
rmutex=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex_for_readcount");
DWORD wait_for_mutex;
Sleep(m_delay);
EnterCriticalSection(&cs);
for(int i=1;i<m_ID;i++)
printf(" ");
printf("读者%d读请求\n",m_ID);
LeaveCriticalSection(&cs);
wait_for_mutex=WaitForSingleObject(rmutex,-1);
readcount++;
if (readcount==1)
EnterCriticalSection(&RP_Write);
ReleaseMutex(rmutex);
EnterCriticalSection(&cs);
for(int j=1;j<m_ID;j++)
printf(" ");
printf("读者%d开始读\n",m_ID);
LeaveCriticalSection(&cs);
Sleep(m_persist);
EnterCriticalSection(&cs);
for(int k=1;k<m_ID;k++)
printf(" ");
printf("读者%d完成读\n",m_ID);
LeaveCriticalSection(&cs);
wait_for_mutex=WaitForSingleObject(rmutex,-1);
readcount--;
if (readcount==0)
LeaveCriticalSection(&RP_Write);
ReleaseMutex(rmutex);
}
void RP_WriterThread(void *p)
{
DWORD m_delay;
DWORD m_persist;
int m_ID;
m_ID=((ThreadInfo *)(p))->serial;
m_delay=(DWORD)(((ThreadInfo *)(p))->delay*INTE_PER_SEC);
m_persist=(DWORD)(((ThreadInfo *)(p))->persist*INTE_PER_SEC);
Sleep(m_delay);
EnterCriticalSection(&cs);
for(int i=1;i<m_ID;i++)
printf(" ");
printf("写者%d写请求\n",m_ID);
LeaveCriticalSection(&cs);
EnterCriticalSection(&RP_Write);
EnterCriticalSection(&cs);
for(int l=1;l<m_ID;l++)
printf(" ");
printf("写者%d开始写\n",m_ID);
LeaveCriticalSection(&cs);
Sleep(m_persist);
EnterCriticalSection(&cs);
for(int q=1;q<m_ID;q++)
printf(" ");
printf("写者%d完成写\n",m_ID);
LeaveCriticalSection(&cs);
LeaveCriticalSection(&RP_Write);
}
void WriterPriority(int num){
DWORD n_thread=num;
DWORD thread_ID;
DWORD wait_for_all;
HANDLE r_Mutex;
HANDLE writerm;
r_Mutex=CreateMutex(NULL,FALSE,"r_Mutex");
writerm=CreateMutex(NULL,FALSE,"writerm");
InitializeCriticalSection(&pright);
InitializeCriticalSection(&w_Mutex);
HANDLE h_Thread[MAX_THREAD_NUM];
readcount=0;
writecount=0;
printf("写者优先:(纵坐标为执行顺序)\n");
for (int i=0;i<(int)(n_thread);i++)
{
if (thread_info[i].entity==READER || thread_info[i].entity=='r')
h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(WP_ReaderThread),&thread_info[i],0,&thread_ID);
else
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);
printf("所有操作完成\n");
}
void WP_ReaderThread(void *p){
DWORD m_delay;
DWORD m_persist;
int m_ID;
m_ID=((ThreadInfo *)(p))->serial;
m_delay=(DWORD)(((ThreadInfo *)(p))->delay*INTE_PER_SEC);
m_persist=(DWORD)(((ThreadInfo *)(p))->persist*INTE_PER_SEC);
HANDLE r_Mutex;
r_Mutex=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"r_Mutex");
DWORD wait_for_rmutex;
Sleep(m_delay);
EnterCriticalSection(&cs);
for(int i=1;i<m_ID;i++)
printf(" ");
printf("读者%d读请求\n",m_ID);
LeaveCriticalSection(&cs);
EnterCriticalSection(&pright);
wait_for_rmutex=WaitForSingleObject(r_Mutex,INFINITE);
if (readcount==0)
EnterCriticalSection(&w_Mutex);
readcount++;
ReleaseMutex(r_Mutex);
LeaveCriticalSection(&pright);
EnterCriticalSection(&cs);
for(int s=1;s<m_ID;s++)
printf(" ");
printf("读者%d开始读\n",m_ID);
LeaveCriticalSection(&cs);
Sleep(m_persist);
EnterCriticalSection(&cs);
for(int r=1;r<m_ID;r++)
printf(" ");
printf("读者%d完成读\n",m_ID);
LeaveCriticalSection(&cs);
wait_for_rmutex=WaitForSingleObject(r_Mutex,INFINITE);
readcount--;
if (readcount==0)
LeaveCriticalSection(&w_Mutex);
ReleaseMutex(r_Mutex);
}
void WP_WriterThread(void *p){
DWORD m_delay;
DWORD m_persist;
int m_ID;
m_ID=((ThreadInfo *)(p))->serial;
m_delay=(DWORD)(((ThreadInfo *)(p))->delay*INTE_PER_SEC);
m_persist=(DWORD)(((ThreadInfo *)(p))->persist*INTE_PER_SEC);
HANDLE writerm;
writerm=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"writerm");
DWORD wait_for_writerm;
Sleep(m_delay);
EnterCriticalSection(&cs);
for(int i=1;i<m_ID;i++)
printf(" ");
printf("写者%d写请求\n",m_ID);
LeaveCriticalSection(&cs);
wait_for_writerm=WaitForSingleObject(writerm,INFINITE);
writecount++;
if (writecount==1)
EnterCriticalSection(&pright);
ReleaseMutex(writerm);
EnterCriticalSection(&w_Mutex);
EnterCriticalSection(&cs);
for(int h=1;h<m_ID;h++)
printf(" ");
printf("写者%d开始写\n",m_ID);
LeaveCriticalSection(&cs);
Sleep(m_persist);
EnterCriticalSection(&cs);
for(int t=1;t<m_ID;t++)
printf(" ");
printf("写者%d完成写\n",m_ID);
LeaveCriticalSection(&cs);
LeaveCriticalSection(&w_Mutex);
wait_for_writerm=WaitForSingleObject(writerm,INFINITE);
writecount--;
if (writecount==0)
LeaveCriticalSection(&pright);
ReleaseMutex(writerm);
}