操作系统课程设计-读者写者问题_第1页
操作系统课程设计-读者写者问题_第2页
操作系统课程设计-读者写者问题_第3页
操作系统课程设计-读者写者问题_第4页
操作系统课程设计-读者写者问题_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

/计算机与信息学院操作系统课程设计报告开题报告该项课程设计的意义;更加深入的了解读者写者问题的算法;加深对线程,进程的理解;加深对"线程同步"概念的理解,理解并应用"信号量机制";熟悉计算机对处理机的管理,了解临界资源的访问方式;了解C++中线程的实现方式,研读API。课程设计的任务多进程/线程编程:读者-写者问题。设置两类进程/线程,一类为读者,一类为写者;随机启动读者或写者;显示读者或写者执行状态;随着进程/线程的执行,更新显示;相关原理及算法描述;整体概况:该程序从大体上来分只有两个模块,即"读者优先"和"写者优先"模块.读者优先:如果没有写者正在操作,则读者不需要等待,用一个整型变量readcount记录读者数目,用于确定是否释放读者线程,readcount的初值为0.当线程开始调入时.每个读者准备读.等待互斥信号,保证对readcount的访问,修改互斥.即readcount++.而当读者线程进行读操作时,则读者数目减少<readcount-->.当readcout=0时,说明所有的读者都已经读完,离开临界区唤醒写者<LeaveCriticalSection<&RP_Write>;>,释放互斥信号<ReleaseMutex<h_Mutex>>.还需要一个互斥对象mutex来实现对全局变量Read_count修改时的互斥.另外,为了实现写-写互斥,需要增加一个临界区对象Write。当写者发出写请求时,必须申请临界区对象的所有权。通过这种方法,可以实现读-写互斥,当Read_count=1时〔即第一个读者到来时,读者线程也必须申请临界区对象的所有权写者优先:写者优先与读者不同之处在于一旦一个写者到来,它应该尽快对文件进行写操作,如果有一个写者在等待,则新到来的读者不允许进行读操作。为此应当填加一个整形变量write_count,用于记录正在等待的写者的数目,write_count的初值为0.当线程开始调入时.只允许一个写者准备读.等待互斥信号,保证对write_count的访问,修改互斥.即write_count++.而当写者线程进行读操作时,则相应写者数目减少<write_count-->.当write_count=0时,说明所有的读者都已经读完,离开临界区唤醒读者,释放互斥信号.为了实现写者优先,应当填加一个临界区对象read,当有写者在写文件或等待时,读者必须阻塞在read上。开发环境;VC++6.0预期设计目标;读者-写者问题的读写操作限制〔包括读者优先和写者优先1.写-写互斥:不能有两个写者同时进行写操作2.读-写互斥:不能同时有一个线程在读,而另一个线程在写。3.读-读允许:可以有一个或多个读者在读。若读者的优先权比写者高,如果读者申请进行读操作时已有另一个读者正在进行读操作,则该读者可直接开始读操作.不必经过别的操件若读者的优先权比写者高,如果第一个写者已经占有了文件的时候.则别的读者必需等待该操作完成后.才能开始读操作.若写者的优先权比读者高,在一个写者提出要访问文件时,就必须使其尽可能的得到文件,而且不用调配。完成课程设计的任务,实现读者写者问题的全部要求,同时可以实现"读者优先"和"写者优先"两种情况,有时间的话,争取实现可视化图形界面。课程设计报告课程设计任务、要求、目的;任务和要求:多进程/线程编程:读者-写者问题。设置两类进程/线程,一类为读者,一类为写者;随机启动读者或写者;显示读者或写者执行状态;随着进程/线程的执行,更新显示;目的:1更加深入的了解读者写者问题的算法;2加深对线程,进程的理解;3加深对"线程同步"概念的理解,理解并应用"信号量机制";4熟悉计算机对处理机的管理,了解临界资源的访问方式;5了解C++中线程的实现方式,研读API。原理及算法描述;写者优先原理图:读者优先原理图:算法描述:读者优先的附加限制:如果读者申请进行读操作时已有另一个读者正在进行读操作,则该读者可直接开始读操作。写者优先的附加限制:如果一个读者申请进行读操作时已有另一个写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。开发环境;VC++6.0重要算法和设计思路描述;整体概况:该程序从大体上来分只有两个模块,即"读者优先"和"写者优先"模块.读者优先:如果没有写者正在操作,则读者不需要等待,用一个整型变量readcount记录读者数目,用于确定是否释放读者线程,readcount的初值为0.当线程开始调入时.每个读者准备读.等待互斥信号,保证对readcount的访问,修改互斥.即readcount++.而当读者线程进行读操作时,则读者数目减少<readcount-->.当readcout=0时,说明所有的读者都已经读完,离开临界区唤醒写者<LeaveCriticalSection<&RP_Write>;>,释放互斥信号<ReleaseMutex<h_Mutex>>.还需要一个互斥对象mutex来实现对全局变量Read_count修改时的互斥.另外,为了实现写-写互斥,需要增加一个临界区对象Write。当写者发出写请求时,必须申请临界区对象的所有权。通过这种方法,可以实现读-写互斥,当Read_count=1时〔即第一个读者到来时,读者线程也必须申请临界区对象的所有权写者优先:写者优先与读者不同之处在于一旦一个写者到来,它应该尽快对文件进行写操作,如果有一个写者在等待,则新到来的读者不允许进行读操作。为此应当填加一个整形变量write_count,用于记录正在等待的写者的数目,write_count的初值为0.当线程开始调入时.只允许一个写者准备读.等待互斥信号,保证对write_count的访问,修改互斥.即write_count++.而当写者线程进行读操作时,则相应写者数目减少<write_count-->.当write_count=0时,说明所有的读者都已经读完,离开临界区唤醒读者,释放互斥信号.为了实现写者优先,应当填加一个临界区对象read,当有写者在写文件或等待时,读者必须阻塞在read上。程序实现数据结构;相关WindowsAPI说明:CreateThread:创建一个在调用进程的地址空间中执行的线程。ExitThreadSleep:对指定的时间间隔挂起当前的执行线程CreateMutex:创建有名或者无名的互斥对象ReleaseMutex:WaitForSingleObject:当发生<1>指定对象处于信号态<2>超时则该函数返回WaitForMultipleObject:任意一个或全部指定对象处于信号态或超时间隔已过时,返回CreateSemapore:创建一个有名或无名信号对象。ReleaseSemapore:InitializeCriticalSection:初始化临界区对象EnterCriticalSection:等待指定临界区对象的所有权。当调用线程被赋予所有权时,返回。LeaveCriticalSection:该函数释放指定临界区对象的所有权。程序实现程序清单;#include<windows.h>//#include<ctype.h>//#include<stdio.h>//#include<string.h>//#include<stdlib.h>//#include<malloc.h>#include<iostream>usingnamespacestd;#defineMAX_PERSON100//最多100人#defineREADER0//读者#defineWRITER1//写者#defineEND-1//结束//#defineRREADER//#defineWWRITERtypedefstruct{ HANDLEm_hThread;//定义处理线程的句柄 intType;//进程类型〔读写 intStartTime;//开始时间 intWorkTime;//运行时间 intID;//进程号}Person;PersonPersons[MAX_PERSON];intNumOfPerson=0;longCurrentTime=0;//基本时间片数intPersonLists[]={//进程队列 1,WRITER,3,5, 2,WRITER,16,5, 3,READER,2,2, 4,WRITER,6,5, 5,READER,4,3, 6,READER,17,7, END,};intNumOfReading=0;intNumOfWriteRequest=0;//申请写进程的个数HANDLEReadSemaphore;//读者信号HANDLEWriteSemaphore;//写者信号boolfinished=false;//所有的读完成//boolwfinished=false;//所有的写完成voidCreatePersonList<int*pPersonList>;boolCreateReader<intStartTime,intWorkTime,intID>;boolCreateWriter<intStartTime,intWorkTime,intID>;DWORDWINAPIReaderProc<LPVOIDlpParam>;DWORDWINAPIWriterProc<LPVOIDlpParam>;intmain<>{ ReadSemaphore=CreateSemaphore<NULL,1,100,NULL>; //创建信号量,当前可用的资源数为1,最大为100 /*HANDLECreateSemaphore< LPSECURITY_ATTRIBUTESlpSemaphoreAttributes,//lpSemaphoreAttributes为安全属性 LONGlInitialCount,//lInitialCount为Semaphore的初始值 LONGlMaximumCount,//lMaximumCount为最大值 LPCTSTRlpName//lpName为Semaphore对象的名字,NULL表示创建匿名Semaphore >;*/ WriteSemaphore=CreateSemaphore<NULL,1,100,NULL>;//创建信号量,当前可用的资源数为1,最大为100 CreatePersonList<PersonLists>;//创建所有读者写者 cout<<"创建所有的读者写者"<<"\n...\n"; CurrentTime=0; while<true> { CurrentTime++; Sleep<300>;//300ms cout<<"当前时间="<<CurrentTime<<endl; if<finished>return0; } //return0;}voidCreatePersonList<int*pPersonLists>{ inti=0; int*pList=pPersonLists; boolRet; while<pList[0]!=END> { switch<pList[1]> { caseREADER: Ret=CreateReader<pList[2],pList[3],pList[0]>; break; caseWRITER: Ret=CreateWriter<pList[2],pList[3],pList[0]>; break; } if<!Ret> printf<"CreatePerson%diswrong\n",pList[0]>; pList+=4;//寻找下一个读者或者写者 }}boolCreateReader<intStartTime,intWorkTime,intID>{ DWORDdwThreadID; if<NumOfPerson>=MAX_PERSON> returnfalse; Person*pPerson=&Persons[NumOfPerson]; pPerson->ID=ID; pPerson->StartTime=StartTime; pPerson->WorkTime=WorkTime; pPerson->Type=READER; NumOfPerson++; //新建进程 pPerson->m_hThread=CreateThread<NULL,0,ReaderProc,<LPVOID>pPerson,0,&dwThreadID>; /*HANDLECreateThread< LPSECURITY_ATTRIBUTESlpThreadAttributes,//pointertosecurityattributes安全属性 DWORDdwStackSize,//initialthreadstacksize堆栈大小 LPTHREAD_START_ROUTINElpStartAddress,//pointertothreadfunction函数指针 LPVOIDlpParameter,//argumentfornewthread DWORDdwCreationFlags,//creationflags LPDWORDlpThreadId//pointertoreceivethreadID >;*/ if<pPerson->m_hThread==NULL> returnfalse; returntrue;}boolCreateWriter<intStartTime,intWorkTime,intID>{ DWORDdwThreadID; if<NumOfPerson>=MAX_PERSON> returnfalse; Person*pPerson=&Persons[NumOfPerson]; pPerson->ID=ID; pPerson->StartTime=StartTime; pPerson->WorkTime=WorkTime; pPerson->Type=WRITER; NumOfPerson++; //新建进程 pPerson->m_hThread=CreateThread<NULL,0,WriterProc,<LPVOID>pPerson,0,&dwThreadID>; /*HANDLECreateThread< LPSECURITY_ATTRIBUTESlpThreadAttributes,//pointertosecurityattributes安全属性 DWORDdwStackSize,//initialthreadstacksize堆栈大小 LPTHREAD_START_ROUTINElpStartAddress,//pointertothreadfunction函数指针 LPVOIDlpParameter,//argumentfornewthread DWORDdwCreationFlags,//creationflags LPDWORDlpThreadId//pointertoreceivethreadID >;*/ if<pPerson->m_hThread==NULL> returnfalse; returntrue;}DWORDWINAPIReaderProc<LPVOIDlpParam>//读过程{ Person*pPerson=<Person*>lpParam; //等待启动时间 while<CurrentTime!=pPerson->StartTime> { //读操作还没有到达执行时间,则等待 } printf<"Reader%disRequesting...\n",pPerson->ID>; printf<"\n\n************************************************\n">; //等待写者请求 //该语句在写者优先的时候是认为写者优先级高于读者,在有写者的时候读者需要等候,而在读者优先的时候,不用判断是否存在写者,有读者时即开始读操作。 while<NumOfWriteRequest!=0> { //NumOfWriteRequest!=0表示有写者在等待,不能读 } //等待ReadSemaphore读信号,即当ReadSemaphore有信号时等待结束,相当于p操作 WaitForSingleObject<ReadSemaphore,INFINITE>; /*DWORDWaitForMultipleObjects< CONSTHANDLE*lpHandles,//pointertotheobject-handlearray DWORDdwMilliseconds//time-outintervalinmilliseconds >;*/ if<NumOfReading==0> { //当第一个读者到了,如果WriteSemaphore信号灯灭了,说明有写者在写,读者必须等待,即互斥写操作 WaitForSingleObject<WriteSemaphore,INFINITE>; } NumOfReading++; //还有读者,但是允许下一个读进程读取,相当于V操作 ReleaseSemaphore<ReadSemaphore,1,NULL>; /*BOOLReleaseSemaphore< HANDLEhSemaphore, //lpReleaseCount参数表示要增加的数值 LONGlReleaseCount,//lpPreviousCount参数用于返回之前的计算值,如果不需要可以设置为NULL LPLONGlpPreviousCount >;*/ //启动读者 pPerson->StartTime=CurrentTime; printf<"Reader%disReadingtheCriticalSection...\n",pPerson->ID>; printf<"\n\n************************************************\n">; while<CurrentTime<=pPerson->StartTime+pPerson->WorkTime> { //..执行读操作 } printf<"Reader%disExit...\n",pPerson->ID>; printf<"\n\n************************************************\n">; WaitForSingleObject<ReadSemaphore,INFINITE>; NumOfReading--; if<NumOfReading==0> { ReleaseSemaphore<WriteSemaphore,1,NULL>;//此时没有读者,可以写 } ReleaseSemaphore<ReadSemaphore,1,NULL>; if<pPerson->ID==6>finished=true;//所有的读写完成 ExitThread<0>; return0;}DWORDWINAPIWriterProc<LPVOIDlpParam>{ Person*pPerson=<Person*>lpParam; //等待启动时间 while<CurrentTime!=pPerson->StartTime> { } printf<"Writer%disRequesting...\n",pPerson->ID>; printf<"\n\n************************************************\n">; NumOfWriteRequest++; //在写者优先的时候需要

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论