读者写者问题

这是一个使用C++实现的Windows平台操作系统课程设计,模拟了读者写者问题。程序提供了两种策略:读者优先和写者优先,通过多线程技术解决并发访问共享资源的冲突。用户可以输入线程数量、线程类型、开始时间和持续时间来模拟不同场景。
摘要由CSDN通过智能技术生成

河北科技大学操作系统课程设计——读者写者问题

#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;         //线程ID
	DWORD wait_for_all;      //等待所有线程结束
	HANDLE rmutex;	//使读者互斥访问readcount
	rmutex=CreateMutex(NULL,FALSE,"mutex_for_readcount");// 
	HANDLE h_Thread[MAX_THREAD_NUM];
	readcount=0;     //初始化readcount
	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;//使读者互斥访问readcount
	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); //P(rmutex)
	readcount++;   //读者数目加1
	if (readcount==1)
		EnterCriticalSection(&RP_Write);  //如果这是第一个读者,进入临界区,开始执行 P(RP_Write);
	ReleaseMutex(rmutex);//V(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);  //P(rmutex)
	readcount--;          //读者数目减1
	if (readcount==0)
		LeaveCriticalSection(&RP_Write); //如果这是最后一个读者,则其释放临界区V(RP_Write);
	
	ReleaseMutex(rmutex); //V(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);//进入临界区  P(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);  //退出后,离开临界区 V(RP_Write);
}
//写者优先处理函数
void WriterPriority(int num){
	DWORD n_thread=num;     //线程数目
	DWORD thread_ID;      //线程ID
	DWORD wait_for_all;   //等待所有线程结束
	HANDLE r_Mutex;       //使读者互斥访问readcount
	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;     //初始化readcount
	writecount=0;     //初始化writecount
	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;       //使读者互斥访问readcount    
	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);  //控制临界资源readcount 
	
	if (readcount==0)
		EnterCriticalSection(&w_Mutex);     //如果这是第一个读者,写者优先进入临界区 P(w_Mutex);
	readcount++;  //读者数目加1
	ReleaseMutex(r_Mutex);//V(r_Mutex)
	LeaveCriticalSection(&pright);//V(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);  //P(r_Mutex)
	readcount--;    //读者数目减1
	if (readcount==0)
		LeaveCriticalSection(&w_Mutex);    //如果读者都退出,写者进入临界区V(w_Mutex);
	
	ReleaseMutex(r_Mutex);//V(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);//P(writerm)
	writecount++;   //写者数目加1
	if (writecount==1)
    	EnterCriticalSection(&pright);//P(pright)
	ReleaseMutex(writerm);//V(writerm)
	
	EnterCriticalSection(&w_Mutex);//P(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);//P(writerm)
	writecount--;   //写者数目减1
	if (writecount==0)
    	LeaveCriticalSection(&pright);
	ReleaseMutex(writerm);//V(writerm)
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值