操作系统课程设计报告读者写着问题.docx
- 文档编号:3540949
- 上传时间:2022-11-23
- 格式:DOCX
- 页数:15
- 大小:70.80KB
操作系统课程设计报告读者写着问题.docx
《操作系统课程设计报告读者写着问题.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计报告读者写着问题.docx(15页珍藏版)》请在冰豆网上搜索。
操作系统课程设计报告读者写着问题
计算机与信息学院
操作系统课程设计报告
专业班级
计算机五班
学生姓名及学号
陈大涛20082677
课程教学班号
0002
任课教师
刘晓平田卫东李琳
实验指导教师
刘晓平田卫东李琳路强
实验地点
逸夫科技楼
2010~2011学年第二学期
一、开题报告
(一)该项课程设计的意义;
1.更加深入的了解读者写者问题的算法;
2.加深对线程,进程的理解;
3.加深对“线程同步”概念的理解,理解并应用“信号量机制”;
4.熟悉计算机对处理机的管理,了解临界资源的访问方式;
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:
创建一个在调用进程的地址空间中执行的线程。
ExitThread
Sleep:
对指定的时间间隔挂起当前的执行线程
CreateMutex:
创建有名或者无名的互斥对象
ReleaseMutex:
WaitForSingleObject:
当发生
(1)指定对象处于信号态
(2)超时则该函数返回
WaitForMultipleObject:
任意一个或全部指定对象处于信号态或超时间隔已过时,返回
CreateSemapore:
创建一个有名或无名信号对象。
ReleaseSemapore:
InitializeCriticalSection:
初始化临界区对象
EnterCriticalSection:
等待指定临界区对象的所有权。
当调用线程被赋予所有权时,返回。
LeaveCriticalSection:
该函数释放指定临界区对象的所有权。
(六)程序实现---程序清单;
#include
//#include
//#include
//#include
//#include
//#include
#include
usingnamespacestd;
#defineMAX_PERSON100//最多100人
#defineREADER0//读者
#defineWRITER1//写者
#defineEND-1//结束
//#defineRREADER
//#defineWWRITER
typedefstruct
{
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<<"当前时间="< 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++; //在写者优先的时候需要用自加来初始信号值,而在读者优先的时是通过读者操作来控制信号值 WaitForSingleObject(WriteSemaphore,INFINITE); //启动写者 pPerson->StartTime=CurrentTime; printf("Writer%disWrittingtheCriticalSection...\n",pPerson->ID); while(CurrentTime<=pPerson->StartTime+pPerson->WorkTime) { //..执行写操作 } printf("Writer%disExit...\n",pPerson->ID); printf("\n\n************************************************\n"); NumOfWriteRequest--; ReleaseSemaphore(WriteSemaphore,1,NULL); if(pPerson->ID==6)finished=true;//所有的读写完成 ExitThread(0); return0; } (
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 课程设计 报告 读者 问题