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

📄 read-first.cpp

📁 读者优先问题。操作限制:1)写-写互斥;2)读-写互斥;3)读-读允许; 读者优先的附加限制:如果一个读者申请进行读操作时已有另一读者正在进行读操作
💻 CPP
字号:
//
//***************************       读者和写者问题         ******************************//
//
//*******************************     (读者优先)   *******************************//
//
//******************    作者:  happy_zh    ****************************//
//
//****************************       2004年12月           ***************************//
//
// 操作限制:
// 1)写-写互斥;
// 2)读-写互斥;
// 3)读-读允许;
// 读者优先的附加限制:如果一个读者申请进行读操作时已有另一读者正在进行读操作,
//  则该读者可直接开始读操作。 


#include <windows.h>
#include <fstream.h>
#include <stdio.h>
#include <string.h>
#include <conio.h>

#define INTE_PER_SEC	1000                   //秒到微秒的乘法因子.	
#define MAX_THREAD_NUM	5                     //本程序允许的读者和写者线程的总数.(最多线程是10个)。

struct ThreadInfo                              //创建线程类,记录在测试文件中指定的每一个线程的参数。
{
	int serial;    //线程号
	char entity;    //是p还是c.(char型的实体线程)。
	double delay;   //double型的延迟(时间)。
	double runtime;  //运行的时间	
};

//全局变量的定义

//临界区对象的声明,用于管理缓冲区的互斥访问.

int          RW_Critical = -1;                  //用于存放读写内容的空间

HANDLE       h_Thread[MAX_THREAD_NUM];			//用于存储每个线程句柄的数组
ThreadInfo	 Thread_Info[MAX_THREAD_NUM];		//线程信息数组
HANDLE       R_mutex;                           //一个写线程的互斥量
HANDLE       W_mutex;							//一个互斥量
double       n_RThread=0;						//实际的正在读的线程数目

//生产消费及辅助函数的声明
void Write(void *p);
void Read(void *p);

int main(int argc,char **argv)
{

	printf("This is reader first ! \n");
	//声明所需变量
	DWORD wait_for_all;
	ifstream inFile;
	if (argc!=2)	{
			printf("Usage:%s <test.txt>\n",argv[0]);
			return 1;
	}


	//打开输入文件,按照规定的格式提取线程等信息.
    inFile.open(argv[1]);
	//inFile.open("test.txt");
	printf("New	Input file is: test.txt\n");

	//提取每个线程的信息到相应数据结构中

	int initlnum=0;
	while (inFile) {
		inFile >> Thread_Info[initlnum].serial;
		inFile >> Thread_Info[initlnum].entity;
		inFile >> Thread_Info[initlnum].delay;
        inFile >> Thread_Info[initlnum].runtime;

	    inFile.get();
		initlnum++;
	}

	//回显获得的线程信息,便于确认正确性

	for (int j=0;j<(int)MAX_THREAD_NUM;j++) {
		int    Temp_serial=Thread_Info[j].serial;
		char   Temp_entity=Thread_Info[j].entity;
		double Temp_delay=Thread_Info[j].delay;
		double Temp_runtime=Thread_Info[j].runtime;
		printf(" \n thread %2d %c %f %f ",Temp_serial,Temp_entity,Temp_delay,Temp_runtime);
		cout<<endl;
	}
	
	printf("\n\n");

	//创建在摸迷过程中几个必要的信号量

	R_mutex=CreateSemaphore(NULL,1,1,"mutex_for_Read");
	W_mutex=CreateSemaphore(NULL,1,1,"mutex_for_Write");
	
	//return 0;

	//创建生产者和消费者线程
	for (int i=0;i<(int)MAX_THREAD_NUM;i++) {
		if (Thread_Info[i].entity=='W')
			h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Write),&(Thread_Info[i]),0,NULL);
		else
			h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Read),&(Thread_Info[i]),0,NULL);
	}

	//主程序等待各个线程的动作结束
	wait_for_all=WaitForMultipleObjects(MAX_THREAD_NUM,h_Thread,TRUE,-1);
	printf("  \n\nAll write and read have finished their work.\n");
	printf("Press any key to quit!\n");
	_getch();
	
	return 0;
	
}



//写进程
void Write(void *p)
{
	DWORD wait_for_semaphore,m_delay,m_runtime;
	int m_serial;
	

	//获得本线程的信息
	m_serial=((ThreadInfo *)(p))->serial;
	m_delay=(DWORD)(((ThreadInfo *)(p))->delay*INTE_PER_SEC);
	m_runtime=(DWORD)(((ThreadInfo *)(p))->runtime*INTE_PER_SEC);
	Sleep(m_delay);       //Sleep 可在指定的时间内挂起当前线程。
	
	//进程开始申请资源
	printf("Writer %2d requires to  write .\n",m_serial);


                                           //确认互斥信号,没有线程在写时,可以进行写操作
	wait_for_semaphore = WaitForSingleObject(W_mutex,-1);

	                                       //如果申请到资源,则写入RW_Critical写入写线程的线程号	
	printf("Writer %2d begins to write.\n",m_serial);
	
	Sleep(m_runtime);                       //必须要执行runtime这么长的时间才释放资源

	RW_Critical=m_serial;
	ReleaseSemaphore(W_mutex,1,NULL);      //固有函数:ReleaseSemaphore 释放对互斥对象的占用,使之成为可用。
   							
	printf("Writer %2d finishes write. \n",m_serial);

}



//读者进程
void Read(void *p)
{
	DWORD wait_for_semaphore,m_delay,m_runtime;
	int m_serial,value;

	
	//提取本线程的信息到本地
	m_serial=((ThreadInfo *)(p))->serial;
	m_delay=(DWORD)(((ThreadInfo *)(p))->delay*INTE_PER_SEC);
	m_runtime=(DWORD)(((ThreadInfo *)(p))->runtime*INTE_PER_SEC);

	Sleep(m_delay);           //开始时间
	
    //请求读
	printf("Reader %2d requests to Read.\n",m_serial);
	wait_for_semaphore = WaitForSingleObject(R_mutex,-1);

    if (n_RThread == 0 )
		wait_for_semaphore = WaitForSingleObject(W_mutex,-1);
		        	
		printf("Reader %2d begins to read. \n",m_serial);
        n_RThread++;
		ReleaseSemaphore(R_mutex,1,NULL);
		

		Sleep(m_runtime);       //执行runtime这么长的时间
		value = RW_Critical;
	
		wait_for_semaphore = WaitForSingleObject(R_mutex,-1);
		n_RThread--;

	if (n_RThread == 0)
		ReleaseSemaphore(W_mutex,1,NULL);
    ReleaseSemaphore(R_mutex,1,NULL);
	printf("Reader %2d finishes reading\n",m_serial);
}	

⌨️ 快捷键说明

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