当前位置:文档之家› 操作系统课程设计报告——读者写者问题

操作系统课程设计报告——读者写者问题

操作系统课程设计课题:读者写者问题******班级:1020552学号*********指导教师:***提交时间:2012/12/30(一)实验目的1.进一步理解“临界资源”的概念;2.把握在多个进程并发执行过程中对临界资源访问时的必要约束条件;3.理解操作系统原理中“互斥”和“同步”的涵义。

(二)实验内容利用程序设计语言编程,模拟并发执行进程的同步与互斥(要求:进程数目不少于3 个)。

(三)、程序分析读者写者问题的定义如下:有一个许多进程共享的数据区,这个数据区可以是一个文件或者主存的一块空间;有一些只读取这个数据区的进程(Reader)和一些只往数据区写数据的进程(Writer),此外还需要满足以下条件:(1)任意多个读进程可以同时读这个文件;(2)一次只有一个写进程可以往文件中写;(3)如果一个写进程正在进行操作,禁止任何读进程度文件。

实验要求用信号量来实现读者写者问题的调度算法。

实验提供了signal类,该类通过P( )、V( )两个方法实现了P、V原语的功能。

实验的任务是修改Creat_Writer()添加写者进程,Creat_Reader()创建读者进程。

Reader_goon()读者进程运行函数。

读优先:要求指一个读者试图进行读操作时,如果这时正有其他读者在进行操作,他可直接开始读操作,而不需要等待。

读者优先的附加限制:如果一个读者申请进行读操作时已有另一读者正在进行读操作,则该读者可直接开始读操作。

写优先:一个读者试图进行读操作时,如果有其他写者在等待进行写操作或正在进行写操作,他要等待该写者完成写操作后才开始读操作。

写者优先的附加限制:如果一个读者申请进行读操作时已有另一写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。

在Windows 7 环境下,创建一个控制台进程,此进程包含n 个线程。

用这n 个线程来表示n 个读者或写者。

每个线程按相应测试数据文件(格式见下)的要求进行读写操作。

用信号量机制分别实现读者优先和写者优先的读者/写者问题。

运行结果显示要求:要求在每个线程创建、发出读写操作申请、开始读写操作和结束读写操作时分别显示一行提示信息,以确定所有处理都遵守相应的读写操作限制。

测试数据文件包括n 行测试数据,分别描述创建的n 个线程是读者还是写者,以及读写操作的开始时间和持续时间。

每行测试数据包括4个字段,各个字段间用空格分隔。

Ø 第一个字段为一个正整数,表示线程序号Ø 第二个字段表示相应线程角色,R 表示读者,W 表示写者Ø 第三个字段为一个正数,表示读/写操作的开始时间:线程创建后,延迟相应时间(单位为秒)后发出对共享资源的读/写请求Ø 第四个字段为一正数,表示读/写操作的持续时间:线程读写请求成功后,开始对共享资源的读/写操作,该操作持续相应时间后结束,并释放共享资源例如:1 R 3 52 W 4 53 R 5 24 R 6 55 W 5.1 3读者写者问题是操作系统中经典的互斥问题:一块数据被多个读者和写者的访问,需要考虑读写互斥、写写互斥(可以同时由多个读者读取)。

具体的又可以分为读者优先和写者优先两类。

读者优先算法:当新的读者到来的时候,若当前正有读者在进行读操作,则该读者无需等待前面的写操作完成,直接进行读操作。

设置两个互斥信号量:rwmutex 用于写者与其他读者/写者互斥的访问共享数据rmutex 用于读者互斥的访问读者计数器readcountvar rwmutex, rmutex :semaphore := 1,1 ;int readcount = 0;cobeginreaderi begin // i=1,2,….P(rmutex);Readcount++;If (readcount == 1) P(rwmutex);V(rmutex);读数据;P(rmutex);Readcount--;If (readcount == 0) V(rwmutex);V(rmutex);EndWriterj begin // j = 1,2,….P(rwmutex);写更新;V(rwmutex);EndCoend写者优先:条件:1)多个读者可以同时进行读2)写者必须互斥(只允许一个写者写,也不能读者写者同时进行)3)写者优先于读者(一旦有写者,则后续读者必须等待,唤醒时优先考虑写者)设置三个互斥信号量:rwmutex 用于写者与其他读者/写者互斥的访问共享数据rmutex 用于读者互斥的访问读者计数器readcountnrmutex 用于写者等待已进入读者退出,所有读者退出前互斥写操作var rwmutex, rmutex,nrmutex :semaphore := 1,1,1 ;int readcount = 0;cobeginreaderi begin // i=1,2,….P(rwmutex);P(rmutex);Readcount++;If (readcount == 1) P(nrmutex); //有读者进入,互斥写操作V(rmutex);V(rwmutex); // 及时释放读写互斥信号量,允许其它读、写进程申请资源读数据;P(rmutex);Readcount--;If (readcount == 0) V(nrmutex); //所有读者退出,允许写更新V(rmutex);EndWriterj begin // j = 1,2,….P(rwmutex); // 互斥后续其它读者、写者P(nrmutex); //如有读者正在读,等待所有读者读完写更新;V(nrmutex); //允许后续新的第一个读者进入后互斥写操作V(rwmutex); //允许后续新读者及其它写者EndCoend/////////////////////////////////////////////////////////////////////////////////////////////////////////////////*---------函数声明---------*/void Creat_Writer(); //添加一个写者void Del_Writer(); //删除一个写者void Creat_Reader(); //添加一个读者void Reader_goon(); //读者进程运行函数void R_Wakeup(); //唤醒等待读者void Del_Reader(); //删除一个读者void Show(); //显示运行状态/*=============== class signal ===============*/class signal //信号量对象.{private:int value;int queue; //用int型数据模拟等待队列.public:signal();signal(int n);int P(); //检查临界资源int V(); //释放临界资源int Get_Value();int Get_Queue();};////////////////////////////////////////////////////////////////////#include<windows.h>#include<fstream>#include<cstdlib>#include<iostream>using namespace std;const int MaxThread=20;struct ThreadInfo{int num;char type;double start;double time;}thread_info[MaxThread];HANDLE hX;HANDLE hWsem;HANDLE thread[MaxThread];int readcount;double totaltime;void WRITEUNIT(int iProcess){printf("Thread %d begins to write.\n",iProcess);Sleep((DWORD)(thread_info[iProcess-1].time*1000));printf("End of thread %d for writing.\n",iProcess);}void READUNIT(int iProcess){printf("Thread %d begins to read.\n",iProcess);Sleep((DWORD)(thread_info[iProcess-1].time*1000));printf("End of thread %d for reading.\n",iProcess);}DWORD WINAPI reader(LPVOID lpVoid){int iProcess = *(int*)lpV oid;Sleep((DWORD)(thread_info[iProcess-1].start*1000));DWORD wait_for=WaitForSingleObject(hX,INFINITE);printf("Thread %d requres reading.\n",iProcess);readcount++;if(readcount==1)WaitForSingleObject(hWsem,INFINITE);ReleaseMutex(hX);READUNIT(iProcess);wait_for=WaitForSingleObject(hX,INFINITE);readcount--;if(readcount==0)ReleaseSemaphore(hWsem,1,0);ReleaseMutex(hX);return iProcess;}DWORD WINAPI writer(LPVOID lpV oid){int iProcess = *(int*)lpV oid;Sleep((DWORD)(thread_info[iProcess-1].start*1000));printf("Thread %d requres writing.\n",iProcess);DWORD wait_for=WaitForSingleObject(hWsem,INFINITE);WRITEUNIT(iProcess);ReleaseSemaphore(hWsem,1,0);return iProcess;}int main(){int threadNum;int threadcount;ifstream file;hX=CreateMutex(NULL, FALSE, NULL);hWsem=CreateSemaphore(NULL,1,1,NULL);//readcount=0;threadcount=0;totaltime=0;file.open("thread.dat",ios::in);if(file==0){printf("File Open Error.\n");return 0;}while(file>>threadNum){thread_info[threadNum-1].num=threadNum;file>>thread_info[threadNum-1].type;file>>thread_info[threadNum-1].start;file>>thread_info[threadNum-1].time;totaltime+=thread_info[threadNum-1].time;switch(thread_info[threadNum-1].type){case 'W':printf("Creating Thread %d for writing.\n",thread_info[threadNum-1].num);thread[threadNum-1] = CreateThread(NULL, 0,writer, &thread_info[threadNum-1].num,0,0);break;case 'R':printf("Creating Thread %d for reading.\n",thread_info[threadNum-1].num);thread[threadNum-1] = CreateThread(NULL, 0,reader, &thread_info[threadNum-1].num,0,0);break;}threadcount++;}file.close();Sleep((DWORD)(totaltime*1000));return 1;}//////////////////////////////////////////////////////////////////////////////////semaphore fmutex = 1 , rdcntmutex = 1 ;// fmutex --> access to file; rdcntmutex --> access to readcountint readcount = 0 ;void reader(){while ( 1 ){P(rdcntmutex);if ( readcount==0)P(fmutex);readcount = readcount + 1 ;V(rdcntmutex);// Do read operationP(rdcntmutex);readcount = readcount - 1 ;if ( readcount==0)V(fmutex);V(rdcntmutex);}}void writer(){while ( 1 ){P(fmutex);// Do write operationV(fmutex);}}/////////////////////////////////////////////////////////////////////////////////////// semaphore fmutex = 1 , rdcntmutex = 1 , wtcntmutex = 1 , queue = 1 ; // fmutex --> access to file; rdcntmutex --> access to readcount// wtcntmutex --> access to writecountint readcount = 0 ,writecount = 0 ;void reader(){while ( 1 ){P(queue);//申请队列信号P(rdcntmutex);//修改readcount,互斥if ( readcount==0)P(fmutex);//access to file 互斥readcount = readcount + 1 ;V(rdcntmutex);//释放V(queue);//释放// Do read operationP(rdcntmutex);readcount = readcount - 1 ;if ( readcount==0)V(fmutex);V(rdcntmutex);}}void writer(){while ( 1 ){P(wtcntmutex);if ( writecount==0)P(queue);writecount = writecount + 1 ;V(wtcntmutex);P(fmutex);// Do write operationV(fmutex);P(wtcntmutex);writecount = writecount - 1 ;if ( writecount==0)V(queue);V(wtcntmutex);}}。

相关主题