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

📄 os2.cpp

📁 计算机操作系统实验,读者和写者问题.设置了缓冲池,有详细的注解.
💻 CPP
字号:
#include <stdio.h>
#include <windows.h> 
#include <fstream.h> 

 

#define INTE_PER_SEC 1000            //每秒时钟中断的数目 
#define MAX_THREAD_NUM 10            //最大线程数 

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) // 读者优先——读者线程信息

{ 
       

       HANDLE h_Mutex;  //互斥变量 

       h_Mutex=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex_for_readcount"); //h_mutex来实现对全局变量readcount修改时的互斥,
	                                                                    //打开这对互斥对象,
	                                                                    //FALSE表示打开此对象的线程不同时具有该互斥对象的所有权
	                                                                    //mutex_for_readcount与已存在的有名互斥对象名相匹配,所以用MUTEX_ALL_ACCESS权限访问已存在的对象

	   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);                  //延迟等待,即屏幕上会有时间间隔地显示,象征表明这段时间正在申请

      printf("\n读者线程 %d 申请读操作.\n",m_serial);
	  

      
	  wait_for_mutex=WaitForSingleObject(h_Mutex,-1);//等待互斥信号,保证对ReadCount 的访问,修改互斥
	                                                

      readcount++;  //经过上面,已有读者到来,读者数目增加 

      
	  if(readcount==1) //第一个读者,等待资源 

       { 

          EnterCriticalSection(&RP_Write); //指定临界区对象的所有权,当前被调用线程被赋予所有权

       } 

       ReleaseMutex(h_Mutex);            //释放互斥信号 

  
           /////////////////////////读文件 

           printf("\n读者线程 %d 开始读操作.\n",m_serial); 

           Sleep(m_persist); //线程持续时间,即屏幕上会有时间间隔地显示,象征表明这段时间正在读操作

  
         //////////////////////退出线程 

       printf("\n读者线程 %d 完成读操作.\n",m_serial); 

       
	   wait_for_mutex=WaitForSingleObject(h_Mutex,-1);//等待互斥信号,保证对ReadCount的访问,修改互斥
	                                                 

	   readcount--;//经过上面,一个读操作完成,读者数目减少  

        if(readcount==0)//如果所有的读者读完,唤醒写者 

        { 

           LeaveCriticalSection(&RP_Write); //释放指定临界区对象的所有权

        } 

       ReleaseMutex(h_Mutex);          //释放互斥信号,与上四行的wait_for_mutex相对应 

} 

  
 

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);

       printf("\n写者线程 %d 申请写操作.\n",m_serial); 
	   

  

       //等待资源 

       EnterCriticalSection(&RP_Write); 

  
       //写文件 

       printf("\n写者线程 %d 开始写操作.\n",m_serial); 

       Sleep(m_persist); 

  
       //退出线程 

       printf("\n写者线程 %d 完成写操作.\n",m_serial); 

       //释放资源 

       LeaveCriticalSection(&RP_Write); 

} 

  


void ReaderPriority(char *file)//读者优先处理函数 

{ 

       DWORD n_thread=0;           //线程数目 ,定义为双字类型

       DWORD thread_ID;            //线程标号,定义为双字类型 

       //DWORD wait_for_all;         //等待所有线程结束,定义为双字类型 

  
       HANDLE h_Mutex; //互斥对象

       h_Mutex=CreateMutex(NULL,FALSE,"mutex_for_readcount");//mutex来实现对全局变量readcount修改时的互斥,
	                                                         //创建这对互斥对象,
	                                                         //FALSE表示创建此对象的线程不同时具有该互斥对象的所有权 
	   HANDLE h_Thread[MAX_THREAD_NUM];//要创建的线程对象的数组  

       ThreadInfo thread_info[MAX_THREAD_NUM];//线程结构体数组,最大线程数为10,用于存储从文本文件中读入的 

        readcount=0;               

       InitializeCriticalSection(&RP_Write);  //初始化临界区对象 


       ifstream ReadFile; 

       ReadFile.open (file); //打开只读文件

       printf("读者优先:\n"); 

       while(ReadFile) 

       { 

              //读入每一个读者,写者的信息,存入thread_info线程结构体数组中 

              ReadFile>>thread_info[n_thread].serial; 

              ReadFile>>thread_info[n_thread].entity; 

              ReadFile>>thread_info[n_thread].delay; 

              ReadFile>>thread_info[n_thread].persist;
			  
			  n_thread++;

              ReadFile.get(); 

       } 

       for(int i=0;i<(int)(n_thread);i++) 

{ 

              
		     if(thread_info[i].entity=='R'||thread_info[i].entity =='r') 

              { 

                     //创建读者进程 

                     h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(RP_ReaderThread),&thread_info[i],0,&thread_ID);//句柄不能被继承,即参数1设为NULL 

              } 

			 if(thread_info[i].entity=='W'||thread_info[i].entity =='w') 

              { 

                     //创建写线程 

                     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 WP_ReaderThread(void *p)//写者优先---读者线程信息  

{ 

       HANDLE h_Mutex1; //互斥变量 

       h_Mutex1=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex1");//h_mutex1来实现对全局变量readcount修改时的互斥,
	                                                       
       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);                  //延迟等待,即屏幕上会有时间间隔地显示,象征表明这段时间正在申请 

  

       printf("\n读者线程 %d 申请读操作.\n",m_serial); 

       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); 

        //读文件 

        printf("\n读者线程 %d 开始读操作.\n",m_serial); 

        Sleep(m_persist); //线程持续时间,即屏幕上会有时间间隔地显示,象征表明这段时间正在读操作

       //退出线程 

   printf("\n读者线程 %d 完成读操作.\n",m_serial); 

   //阻塞互斥对象Mutex2,保证对readcount的访问,修改互斥 

   wait_for_mutex2=WaitForSingleObject(h_Mutex2,-1); 

   readcount--; 

   if(readcount==0) 

   { 

          //最后一个读者,唤醒写者 

          LeaveCriticalSection(&cs_Write); 

   } 

   ReleaseMutex(h_Mutex2);  //释放互斥信号 

} 

  

  

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");//h_mutex3来实现对全局变量writecount修改时的互斥,
	                                                       //打开这对互斥对象,
	                                                       //FALSE表示打开此对象的线程不同时具有该互斥对象的所有权
	                                                      //mutex_for_readcount与已存在的有名互斥对象名相匹配,所以用MUTEX_ALL_ACCESS权限访问已存在的对象 

  

  

       //从参数中获得信息 

       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);                  //延迟等待,即屏幕上会有时间间隔地显示,象征表明这段时间正在申请 

       printf("\n写者线程%d 申请写操作.\n",m_serial); 

       wait_for_mutex3=WaitForSingleObject(h_Mutex3,-1); 

       writecount++;               //经过上面,已有写者到来,所以修改写者数目 

       if(writecount==1)//第一个写者,等待资源

       { 

              EnterCriticalSection(&cs_Read);//指定临界区对象的所有权,当前被调用线程被赋予所有权 

       } 

       ReleaseMutex(h_Mutex3); //释放互斥信号h_Mutex3



       EnterCriticalSection(&cs_Write);
	   









       printf("\n写者线程 %d 开始写操作.\n",m_serial); 

       Sleep(m_persist);//线程持续时间,即屏幕上会有时间间隔地显示,象征表明这段时间正在写操作 

       printf("\n写者线程%d 完成写操作.\n",m_serial); 

       LeaveCriticalSection(&cs_Write);
	   









  

       wait_for_mutex3=WaitForSingleObject(h_Mutex3,-1); //等待互斥信号,保证对writecount的访问,修改互斥

       writecount--; 

       if(writecount==0) 

       { 

              LeaveCriticalSection(&cs_Read); 

       } 

        ReleaseMutex(h_Mutex3); 

} 


  

void WriterPriority(char * file)//写者优先处理函数  

{ 

       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 ReadFile; 

       ReadFile.open (file); 

       printf("写者优先:\n"); 

       while(ReadFile) 

       { 

              ReadFile>>thread_info[n_thread].serial; 

              ReadFile>>thread_info[n_thread].entity; 

              ReadFile>>thread_info[n_thread].delay; 

              ReadFile>>thread_info[n_thread].persist;
			  
			  n_thread++;

              ReadFile.get(); 

       } 

       for(int i=0;i<(int)(n_thread);i++) 

       { 

              if(thread_info[i].entity=='R'||thread_info[i].entity =='r') 

              { 

                     //创建读者进程 

                  h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(WP_ReaderThread),&thread_info[i],0,&thread_ID); 

              } 

              if(thread_info[i].entity=='W'||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); 

       //printf("All reader and writer have finished operating.\n"); 

} 

  



void main() 

{ 

       int select; 

       while(1) 

       { 

              printf("*************************************\n"); 

              printf("   1.读者优先\n"); 

              printf("   2.写者优先\n"); 

              printf("   0.退出\n"); 

              printf("*************************************\n"); 

              printf("请选择: "); 

              
			  scanf("%d",&select);
			  switch(select)
			  {
			  case 1:
				  ReaderPriority("thread.txt");
				  Sleep(20000);
				  printf("\n所有读写操作均已完成.\n");
				  break;
			  case 2:
				  WriterPriority("thread.txt");
				  Sleep(20000);
				  printf("\n所有读写操作均已完成.\n");
				  break;
			  case 0:
				  exit(0); 
			  }
	   } 
} 

⌨️ 快捷键说明

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