⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 czh.txt

📁 通过实现经典的读者写者问题
💻 TXT
字号:
#include <windows.h>
#include <conio.h> 
#include "fstream.h" 

//全局变量
int readcount=0;          //读者数目
int writecount=0;         //写者数目
/*
关键代码段是指一个小代码段,在代码能够执行前,它必须独占对某些共享资源的访问权。
这是让若干行代码能够“以原子操作方式”来使用资源的一种方法。
*/
CRITICAL_SECTION RP_Write; //临界区
CRITICAL_SECTION cs_Write;
CRITICAL_SECTION cs_Read;

struct ThreadInfo               //线程信息
{	int Threadhao;              //线程序号
	char ThreadClass;           //线程类别
	double ThreadStartTime;     //线程开始时间
	double ThreadRunTime;       //线程读写持续时间
};


void ReaderFun(char* file);//读者优先函数	
void R_ReaderThread(void *p);//处理读者优先读者线程
void R_WriterThread(void *p);//处理读者优先写者线程


void WriterFun(char* file);  
void W_ReaderThread(void *p);
void W_WriterThread(void *p);


int main()
{
	char select;
	while (true)
	{
		cout<<"***************本程序实现读者-写者问题**************\n"<<endl;
		cout<<"              1:读者优先"<<endl;
        cout<<"              2:写者优先"<<endl;
		cout<<"              3:退出"<<endl;
		cout<<"\n****************************************************"<<endl;
		cout<<"请选择要进行的操作:"<<endl;
    	do
		{
			cin>>select;
			if(select!='1' && select!='2' && select!='3')
				cout<<"你操作有误,请重试!"<<endl;
		}while (select!='1' && select!='2' && select!='3');
		system("cls");
		if (select=='3')
			return 0;//退出
		else if (select=='1')//调用读者优先
				ReaderFun("peizhi.txt");
			 else if(select=='2')//调用写者优先
			    WriterFun("peizhi.txt");
		cout<<"\n是否还有继续?  1. 继续   2.退出"<<endl;;
		do
		{
			cin>>select;
			if(select!='1' && select!='2' )
				cout<<"你操作有误,请重试!"<<endl;
		}while (select!='1' && select!='2');
		if(select=='2')
			return 0;//	退出
		system("cls");
	}
	return 0;
}

//读者优先函数
void ReaderFun(char* file)
{
	DWORD n_thread=0;        //线程数初值为0
	DWORD thread_ID;         //线程ID
	DWORD wait_for_all;      //等待所有线程结束
	//临界资源
	HANDLE h_Mutex;
	//互斥对象(h_Mutex)确保线程拥有对单个资源的互斥访问权
	h_Mutex=CreateMutex(NULL,FALSE,"mutex_for_readcount");
    /*创建互斥对象,
    NULL表示创建带有默认安全性的内核对象
	FALSE表示该互斥对象没有被任何线程所拥有
	mutex_for_readcount是为内核对象赋予名字。
	*/

	HANDLE h_Thread[64];	//线程对象数组,最大64
	ThreadInfo thread_info[64];
	readcount=0;     
	InitializeCriticalSection(&RP_Write);  //初始化临界区
	ifstream inFile;
	inFile.open(file);                     
	cout<<"读者优先:\n"<<endl;
	while (inFile)
	{
		//读入每一个读者、写者的信息
		inFile>>thread_info[n_thread].Threadhao>>thread_info[n_thread].ThreadClass
		>>thread_info[n_thread].ThreadStartTime>>thread_info[n_thread].ThreadRunTime;
		if (-1 == inFile.get())
			break;
		n_thread++;//线程数加一
	}
	for (int i=0;i<(int)(n_thread);i++)
	{
		if (thread_info[i].ThreadClass=='r')
			//创建读者线程
			h_Thread[i]=CreateThread(NULL,0,\
			(LPTHREAD_START_ROUTINE)(R_ReaderThread),\
			&thread_info[i],0,&thread_ID);
		    /*
			NULL表示创建带有默认安全性的内核对象

			0表示CreateThread就保留一个区域,并且将链接程序
			嵌入. EXE文件的/ STACK链接程序开关信息指明
            的存储器容量分配给线程堆栈。

            (LPTHREAD_START_ROUTINE)(R_ReaderThread)表示新线程执行的线程函数的地址

            &thread_info[i]表示在线程启动执行时将该参数传递给线程函数。

		    0表示读者线程创建后可以立即进行调度

            &thread_ID表示CreateThread使用这个地址来存放系统分配
		    给新读者线程的I D
			*/
		else
			//创建写者线程
			h_Thread[i]=CreateThread(NULL,0,\
			(LPTHREAD_START_ROUTINE)(R_WriterThread),\
			&thread_info[i],0,&thread_ID);
	}
	
	wait_for_all=WaitForMultipleObjects(n_thread,h_Thread,TRUE,-1);
	/*
	等待函数可使线程自愿进入等待状态,直到一个特定的内核对象变为已通知状态为止
	n_thread表示线程数量。
	h_Thread是指向线程对象句柄的数组的指针。
	ture表示:在所有线程对象变为已通知状态之前,该函数将不允许调用线程运行
	参数 -1 告诉系统,调用线程愿意永远等待下去(无限时间量),直到该进程终止运行。
	*/
	cout<<"所有的读者和写者线程完成操作."<<endl;
}

//读者优先-----读者线程
void R_ReaderThread(void *p)
{
	//互斥变量
	HANDLE h_Mutex;
	h_Mutex=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex_for_readcount");
	/*
         获得它自己进程与现有互斥对象相关的句柄:
	*/
	DWORD wait_for_mutex;   //等待互斥变量所有权
	DWORD m_delay;          //延迟时间
	DWORD m_ThreadRunTime;        //读文件持续时间
	int m_Threadhao;           //线程序号
	m_Threadhao=((ThreadInfo *)(p))->Threadhao;
	m_delay=(DWORD)(((ThreadInfo *)(p))->ThreadStartTime*100);
	m_ThreadRunTime=(DWORD)(((ThreadInfo *)(p))->ThreadRunTime*100);
	Sleep(m_delay);                                   //延迟等待
	cout<<"读者线程 "<<m_Threadhao<<" 发出读请求."<<endl;
	wait_for_mutex=WaitForSingleObject(h_Mutex,-1);   //等待互斥信号,保证对readcount的访问、
													  //修改互斥
	readcount++;                                      //读者数目加一
	if (readcount==1)
		EnterCriticalSection(&RP_Write);//禁止写者进入	          
	ReleaseMutex(h_Mutex);//释放互斥对象,允许下个读者继续读:
	//读文件
	cout<<"读者线程 "<<m_Threadhao<<" 开始读文件."<<endl;
	Sleep(m_ThreadRunTime);
	//退出线程
	cout<<"读者线程 "<<m_Threadhao<<" 完成读文件."<<endl;
	wait_for_mutex=WaitForSingleObject(h_Mutex,-1);  //等待互斥信号,保证对readcount的访问、修改互斥
	readcount--;                                     //读者数目减少
	if (readcount==0)
		LeaveCriticalSection(&RP_Write);	         //如果所有读者读完,唤醒写者
	ReleaseMutex(h_Mutex);//释放互斥信号
}

//读者优先-----写者线程
void R_WriterThread(void *p)
{
	DWORD m_delay;          //延迟时间
	DWORD m_ThreadRunTime;  //读文件持续时间
	int m_Threadhao;        //线程序号
	//从参数中获得信息
	m_Threadhao=((ThreadInfo *)(p))->Threadhao;
	m_delay=(DWORD)(((ThreadInfo *)(p))->ThreadStartTime*100);
	m_ThreadRunTime=(DWORD)(((ThreadInfo *)(p))->ThreadRunTime*100);
	Sleep(m_delay);                                   //延迟等待
	cout<<"写者线程 "<<m_Threadhao<<" 发出写请求."<<endl;
	EnterCriticalSection(&RP_Write);//禁止下一位写者进入
	//写文件
	cout<<"写者线程 "<<m_Threadhao<<" 开始写文件."<<endl;
	Sleep(m_ThreadRunTime);
	//退出线程
	cout<<"写者线程 "<<m_Threadhao<<" 完成写文件."<<endl;
	LeaveCriticalSection(&RP_Write);	         //如果所有读者读完,唤醒写者

}

//写者优先处理函数
void WriterFun(char* file)
{
	DWORD n_thread=0;        //线程数目
	DWORD thread_ID;         //线程ID
	DWORD wait_for_all;      //等待所有线程结束
	//互斥对象
	HANDLE h_Mutex1, h_Mutex2, h_Mutex3;
	h_Mutex1 = CreateMutex(NULL, FALSE, "mutex_for_writecount");
	h_Mutex2 = CreateMutex(NULL, FALSE, "mutex_for_readcount");
	h_Mutex3 = CreateMutex(NULL, FALSE, "mutex_for_read");
	//线程对象数组
	HANDLE h_Thread[64];
	ThreadInfo thread_info[64];
	readcount=0;     //初始化readcount
	InitializeCriticalSection(&cs_Write);  //初始化临界区
	InitializeCriticalSection(&cs_Read);
	ifstream inFile;
	inFile.open(file);                     //打开文件
	cout<<"写者优先:\n"<<endl;
	while (inFile)
	{
		//读入每一个读者、写者的信息
		inFile>>thread_info[n_thread].Threadhao>>thread_info[n_thread].ThreadClass
		>>thread_info[n_thread].ThreadStartTime>>thread_info[n_thread].ThreadRunTime;
		
		if(-1 == inFile.get())
			break;
		n_thread++;//线程数加一
	}
	for (int i=0;i<(int)(n_thread);i++)
	{
		if (thread_info[i].ThreadClass=='r')
			//创建读者线程
			h_Thread[i]=CreateThread(NULL,0,\
			(LPTHREAD_START_ROUTINE)(W_ReaderThread),\
			&thread_info[i],0,&thread_ID);
		else
			//创建写者线程
			h_Thread[i]=CreateThread(NULL,0,\
			(LPTHREAD_START_ROUTINE)(W_WriterThread),\
			&thread_info[i],0,&thread_ID);
	}
	//等待所有线程结束
	wait_for_all=WaitForMultipleObjects(n_thread,h_Thread,TRUE,-1);
	cout<<"所有的读者和写者线程完成操作."<<endl;
}

//写者优先-----写者线程
void W_WriterThread(void *p)
{
	//互斥变量
	HANDLE h_Mutex1;
	h_Mutex1 = OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex_for_writecount");

	DWORD wait_for_mutex;   //等待互斥变量所有权
	DWORD m_delay;          //延迟时间
	DWORD m_ThreadRunTime;        //读文件持时续间
	int m_Threadhao;           //线程序号
	m_Threadhao=((ThreadInfo *)(p))->Threadhao;
	m_delay=(DWORD)(((ThreadInfo *)(p))->ThreadStartTime*100);//每秒时钟中断100次
	m_ThreadRunTime=(DWORD)(((ThreadInfo *)(p))->ThreadRunTime*100);//每秒时钟中断100次
	Sleep(m_delay);                                   
	cout<<"写者线程 "<<m_Threadhao<<" 发出写请求."<<endl;

	wait_for_mutex=WaitForSingleObject(h_Mutex1,-1);  
	writecount++;
	if (writecount==1)
		EnterCriticalSection(&cs_Read);
	ReleaseMutex(h_Mutex1);

	EnterCriticalSection(&cs_Write);
	cout<<"写者线程 "<<m_Threadhao<<" 开始写文件."<<endl;
	Sleep(m_ThreadRunTime);
	cout<<"写者线程 "<<m_Threadhao<<" 完成写文件."<<endl;
	LeaveCriticalSection(&cs_Write);

	wait_for_mutex=WaitForSingleObject(h_Mutex1,-1);  
	writecount--;
	if(writecount == 0)
		LeaveCriticalSection(&cs_Read);
	ReleaseMutex(h_Mutex1);
}

//写者优先-----读者线程
void W_ReaderThread(void *p)
{
	HANDLE h_Mutex2, h_Mutex3;
	h_Mutex2 = OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex_for_readcount");
	h_Mutex3 = OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex_for_read");

	DWORD wait_for_mutex, wait_for_mutex1;   //等待互斥变量所有权
	DWORD m_delay;          //延迟时间
	DWORD m_ThreadRunTime;        //读文件持续时间
	int m_Threadhao;           //线程序号

	m_Threadhao=((ThreadInfo *)(p))->Threadhao;
	m_delay=(DWORD)(((ThreadInfo *)(p))->ThreadStartTime*100);
	m_ThreadRunTime=(DWORD)(((ThreadInfo *)(p))->ThreadRunTime*100);
	Sleep(m_delay);
	cout<<"读者线程 "<<m_Threadhao<<" 发出读请求."<<endl;

	wait_for_mutex1=WaitForSingleObject(h_Mutex3,-1);
	EnterCriticalSection(&cs_Read);
	LeaveCriticalSection(&cs_Read);
	ReleaseMutex(h_Mutex3);

	wait_for_mutex=WaitForSingleObject(h_Mutex2,-1); 
	readcount++;
	if (readcount == 1)
		EnterCriticalSection(&cs_Write);
	ReleaseMutex(h_Mutex2);

	cout<<"读者线程 "<<m_Threadhao<<" 开始读文件."<<endl;
	Sleep(m_ThreadRunTime);
	cout<<"读者线程 "<<m_Threadhao<<" 完成读文件."<<endl;

	wait_for_mutex=WaitForSingleObject(h_Mutex2,-1);
	readcount--;
	if (readcount == 0)
		LeaveCriticalSection(&cs_Write);
	ReleaseMutex(h_Mutex2);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -