操作系统原理课程设计读者写者问题的实现.docx
《操作系统原理课程设计读者写者问题的实现.docx》由会员分享,可在线阅读,更多相关《操作系统原理课程设计读者写者问题的实现.docx(14页珍藏版)》请在冰豆网上搜索。
操作系统原理课程设计读者写者问题的实现
*******************
实践教学
*******************
计算机与通信学院
2012年秋季学期
操作系统原理课程设计
题目:
读者-写者问题的实现
专业班级:
姓名:
学号:
指导教师:
成绩:
目录
摘要2
1.设计思想3
2.各模块的伪码算法4
3.函数关系调用图6
4.程序测试结果7
设计总结10
参考文献11
致谢12
摘要
本设计的读者写者问题,是指一些进程共享一个数据区。
数据区可以使一个文件、一块内存空间或者一组寄存器。
Reader进程只能读数据区中的数据,而writer进程必须与其他进程互斥地访问共享对象的同步问题。
读者写者问题可以这样的描述,有一群写者和一群读者,写者在写同一本书,读者也在读这本书,多个读者可以同时读这本书。
但是,只能有一个写者在写书,并且,读者必写者优先,也就是说,读者和写者同时提出请求时,读者优先。
当读者提出请求时需要有一个互斥操作,另外,需要有一个信号量S来确定当前是否可操作。
本设计方案就是通过利用记录型信号量对读者写者问题的解决过程进行模拟演示,形象地阐述记录型信号量机制的工作原理。
关键词:
共享对象,互斥,同步,信号量
1.设计思想
本设计借助C语言实现进程同步和互斥的经典问题--读者写者问题,用高级语言编写和调试一个进程同步程序,以加深对进程同步机制的理解。
通过用C语言模拟进程同步实现,加深理解有关进程同步和互斥机制的概念及P、V操作的应用。
学生通过该题目的设计过程,掌握读者、写者问题的原理、软件开发方法并提高解决实际问题的能力。
在Windows环境下,创建一个包含n个线程的控制台进程。
用这n个线每个线程按相应测试数据文件的要求,进行读写操作。
程来表示n个读者或写者。
请用信号量机制分别实现读者优先和写者优先的读者-写者问题。
将所有的读者和所有的写者分别放进两个等待队列中,当读允许时就让读者队列释放一个或多个读者,当写允许时,释放第一个写者操作。
读者-写者的读写限制(包括读者优先和写者优先)
1)写-写互斥,即不能有两个写者同时进行写操作;
2)读-写互斥,即不能同时有一个读者在读,同时却有一个写者在写;
3)读读允许,即可以有2个以上的读者同时读;
4)读者优先附加条件:
如果一个读者申请进行读操作,同时又有一个读操作正在进行读操作,则该读者可以直接开始读操作;
5)写者优先附加条件:
如果一个读者申请进行读操作时已经有一个写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。
2.各模块的伪码算法
读者优先算法:
设置两个互斥信号量:
rwmutex用于写者与其他读者/写者互斥的访问共享数据
rmutex 用于读者互斥的访问
读者计数器readcount
semaphorerwmutex=1,rmutex=1;
intreadcount=0;
readeri //读者进程i=1,2,….
do{
P(rmutex); //读者互斥
readcount++;//读者数加1
if(readcount==1)P(rwmutex); //读者写者互斥
V(rmutex);
读者读数据;
P(rmutex);
Readcount--;
if(readcount==0)V(rwmutex);
V(rmutex);
}while
(1);
writerj//写者进程j=1,2,….
do{
P(rwmutex);
写文件;
V(rwmutex);
}while
(1);
写者优先算法:
设置三个互斥信号量:
rwmutex用于写者与其他读者/写者互斥的访问共享数据
rmutex 用于读者互斥的访问
读者计数器readcount
nrmutex用于写者等待已进入读者退出,所有读者退出前互斥写操作
semaphorerwmutex=1,rmutex=1,nrmutex=1;
intreadcount=0;
readeri //读者进程i=1,2,….
do{
P(rwmutex);
P(rmutex);
readcount++;
if(readcount==1)P(nrmutex);//有读者进入,互斥写操作
V(rmutex);
V(rwmutex);//及时释放读写互斥信号量,允许其它读、写进程申请资源
读数据;
P(rmutex);
readcount--;
if(readcount==0)V(nrmutex);//所有读者退出,允许写更新
V(rmutex);
}while
(1);
writerj//写者进程j=1,2,….
do{
P(rwmutex); //互斥后续其它读者、写者
P(nrmutex); //如有读者正在读,等待所有读者读完
写更新;
V(nrmutex); //允许后续新的第一个读者进入后互斥写操作
V(rwmutex); //允许后续新读者及其它写者
}while
(1);
3.函数关系调用图
图1函数关系图
4.程序测试结果
测试数据文件包括n行测试数据,分别描述创建的n个线程是读者还是写者,以及读写操作的开始时间和持续时间.每行测试数据包括四个字段,各字段间用空格分隔。
第一字段为一个正整数,表示线程序号.第二字段表示相应线程角色,R表示读者是,W表示写者。
第三字段为一个正数,表示读写操作的开始时间。
线程创建后,延时相应时间(单位为秒)后发出对共享资源的读写申请.第四字段为一个正数,表示读写操作的持续时间。
当线程读写申请成功后,开始对共享资源的读写操作,该操作持续相应时间后结束,并释放共享资源。
在读者写者同时在队列中等待申请资时,读者优先调用资源.而且如果一个读者申请进行读操作时已有另一读者正在进行读操作,则该读者可直接开始读操作,即读读允许。
图2进程1、2的测试结果
如图2所示,进程1是W操作,在时间3时进入队列,运行时间是5,即在时间8时,进程1退出。
在它进入时没有进程占用资源,它既占用资源;知道它释放资源,等候的进程有3,4,5;
图3进程3、5的测试结果
如图3所示,进程5是R操作,在时间4时进入队列,运行时间是3,进程3是R操作,在时间5时进入队列,运行时间是2,在它们进入时,进程1占用资源,它等待资源,当进程1释放资源后,由于读者优先,进程3,5同时调运资源,因此在时间11时,进程3退出,在时间12时,进程5退出;
图4进程2、4、6的测试结果
如图4所示,进程4是W操作,在时间5时进入队列,运行时间是5,在它进入时进程1占用资源,它等待资源,当进程1释放资源后,由于读者优先,进程3,5占用资源,它依然等待,直到进程3,5都结束,即进程4在时间12时开始调用资源;进程2是R操作,在时间16时进入队列,运行时间是5,在它进入时进程4占用资源,它等待资源,当4释放时占用资源后,进程2开始运行;进程6是R操作,在时间17时进入队列,运行时间是7,在它进入时进程2占用资源,它等待进程2释放后最后调用资源。
设计总结
课程设计是培养学生综合运用所学知识,发现,提出,分析和解决实际问题,锻炼实践能力的重要环节,是对学生实际工作能力的具体训练和考察过程。
此次操作系统课程设计,我的感慨颇多,的确,从选题到定稿,从理论到实践,在整整两星期的日子里,我学到很多的东西;同时不仅巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。
通过这次课程设计我懂得了理论与实际相结合的重要性,只有理论知识是远远不够的,所以只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正的服务于社会,从而提高自己的实际动手能力和独立思考的能力。
在设计的过程中遇到问题,可以说是困难重重,难免会遇到过各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固。
因此,在以后的学习中要多下苦功,加强基础知识的学习,并且培养自己的动手实践能力。
参考文献
1.汤子瀛,哲凤屏.计算机操作系统,西安:
电子科技大学学出版社,2002年
2.王清,李光明.计算机操作系统,北京:
冶金工业出版社,2003年3月
3.孙钟秀等.操作系统教程.北京:
高等教育出版社,2008年4月
4.曾明. Linux操作系统应用教程.西安:
陕西科学技术出版社,2005年
5.张丽芬,刘利雄.操作系统实验教程.北京:
清华大学出版社,2006年
6.孟静.操作系统教程——原理和实例分析.北京:
高等教育出版社,2001年
7.周长林.计算机操作系统教程.北京:
高等教育出版社,2011年12月
8.张尧学.计算机操作系统教程.北京:
清华大学出版社,2006年10月
9.任满杰.操作系统原理实用教程.北京:
电子工业出版社,2006年1月
致谢
这次课程设计培养了我耐心、缜密、全面地思考问题的能力,从而加快了问题解决的速度、提高了个人的工作效率,以及锻炼了使问题在短时间内得以解决的品质。
我从“纸上谈兵”到可以自己动脑动手分析调试程序,收获不少。
首先要感谢学校给我这次实践的机会,给了自己一个舞台。
这不仅是对自身的检验,而且增加了我编写代码的功力。
还有多亏了老师们从理论到上机亲自指导的辛苦教授,给予了我们最大帮助和全面指导。
在这里,尤其感谢我的指导老师朱红蕾老师,你不辞辛苦的给我们耐心指导。
在这里,我衷心向你们致谢!
最后还要感谢热心的同学们,在我陷入误区的时候,是他们热心的帮助使我摆脱困境。
最后衷心感谢所有给予我帮助和指导的老师和同学,没有他们的帮助我的程序也不会完成得这么顺利。
源代码:
#include
#include
#include
#include
#include
#include
#defineMAX_PERSON100
#defineREADER0//读者
#defineWRITER1//写者
#defineEND-1
#defineRREADER
#defineWWRITER
typedefstruct_Person{
HANDLEm_hThread;//定义处理线程的句柄
intm_nType;//进程类型(读写)
intm_nStartTime;//开始时间
intm_nWorkTime;//运行时间
intm_nID;//进程号
}Person;
Persong_Persons[MAX_PERSON];
intg_NumPerson=0;
longg_CurrentTime=0;//基本时间片数
intg_PersonLists[]={//进程队列
1,W,3,5,2,W,16,5,3,R,5,2,
4,W,6,5,5,R,4,3,6,R,17,7,
END,
};
intg_NumOfReading=0;
intg_NumOfWriteRequest=0;//申请写进程的个数
HANDLEg_hReadSemaphore;//读者信号
HANDLEg_hWriteSemaphore;//写者信号
boolfinished=false;//所有的读完成
//boolwfinished=false;//所有的写完成
voidCreatePersonList(int*pPersonList);
boolCreateReader(intStartTime,intWorkTime,intID);
boolCreateWriter(intStartTime,intWorkTime,intID);
DWORDWINAPIReaderProc(LPVOIDlpParam);
DWORDWINAPIWriterProc(LPVOIDlpParam);
intmain()
{
g_hReadSemaphore=CreateSemaphore(NULL,1,100,NULL);//创建信号灯,当前可用的资源数为1,最大为100
g_hWriteSemaphore=CreateSemaphore(NULL,1,100,NULL);//创建信号灯,当前可用的资源数为1,最大为100
CreatePersonList(g_PersonLists);//创建所有的读者和写者
printf("Createdallthereaderandwriter\n...\n");
g_CurrentTime=0;
while(true)
{
g_CurrentTime++;
Sleep(300);//300ms
printf("CurrentTime=%d\n",g_CurrentTime);
if(finished)return0;
}//return0;
}
voidCreatePersonList(int*pPersonLists)
{
inti=0;
int*pList=pPersonLists;
boolRet;
while(pList[0]!
=END)
{
switch(pList[1])
{
caseR:
Ret=CreateReader(pList[2],pList[3],pList[0]);//351,w452,523,654
break;
caseW:
Ret=CreateWriter(pList[2],pList[3],pList[0]);
break;
}
if(!
Ret)
printf("CreatePerson%diswrong\n",pList[0]);
pList+=4;//movetonextpersonlist
}
}
DWORDWINAPIReaderProc(LPVOIDlpParam)//读过程
{
Person*pPerson=(Person*)lpParam;
//waitforthestarttime
while(g_CurrentTime!
=pPerson->m_nStartTime)
{}
printf("Reader%disRequesting...\n",pPerson->m_nID);
printf("\n\n************************************************\n");
//waitforthewriterequest
WaitForSingleObject(g_hReadSemaphore,INFINITE);
if(g_NumOfReading==0)
{
WaitForSingleObject(g_hWriteSemaphore,INFINITE);
}
g_NumOfReading++;
ReleaseSemaphore(g_hReadSemaphore,1,NULL);
pPerson->m_nStartTime=g_CurrentTime;
printf("Reader%disReadingtheSharedBuffer...\n",pPerson->m_nID);
printf("\n\n************************************************\n");
while(g_CurrentTime<=pPerson->m_nStartTime+pPerson->m_nWorkTime)
{}
printf("Reader%disExit...\n",pPerson->m_nID);
printf("\n\n************************************************\n");
WaitForSingleObject(g_hReadSemaphore,INFINITE);
g_NumOfReading--;
if(g_NumOfReading==0)
{
ReleaseSemaphore(g_hWriteSemaphore,1,NULL);//此时没有读者,可以写
}
ReleaseSemaphore(g_hReadSemaphore,1,NULL);
if(pPerson->m_nID==4)finished=true;//所有的读写完成
ExitThread(0);
return0;
}
DWORDWINAPIWriterProc(LPVOIDlpParam)
{
Person*pPerson=(Person*)lpParam;
//waitforthestarttime
while(g_CurrentTime!
=pPerson->m_nStartTime)
{}
printf("Writer%disRequesting...\n",pPerson->m_nID);
printf("\n\n************************************************\n");
WaitForSingleObject(g_hWriteSemaphore,INFINITE);
//modifythewriter'srealstarttime
pPerson->m_nStartTime=g_CurrentTime;
printf("Writer%disWrittingtheSharedBuffer...\n",pPerson->m_nID);
while(g_CurrentTime<=pPerson->m_nStartTime+pPerson->m_nWorkTime)
{}
printf("Writer%disExit...\n",pPerson->m_nID);
printf("\n\n************************************************\n");
//g_NumOfWriteRequest--;
ReleaseSemaphore(g_hWriteSemaphore,1,NULL);
if(pPerson->m_nID==4)finished=true;//所有的读写完成
ExitThread(0);
return0;
}
boolCreateReader(intStartTime,intWorkTime,intID)//写过程
{
DWORDdwThreadID;
if(g_NumPerson>=MAX_PERSON)
returnfalse;
Person*pPerson=&g_Persons[g_NumPerson];
pPerson->m_nID=ID;
pPerson->m_nStartTime=StartTime;
pPerson->m_nWorkTime=WorkTime;
pPerson->m_nType=READER;
g_NumPerson++;
//创建一个新的线程
pPerson->m_hThread=
CreateThread(NULL,0,ReaderProc,(LPVOID)pPerson,0,&dwThreadID);
if(pPerson->m_hThread==NULL)
returnfalse;
returntrue;
}
boolCreateWriter(intStartTime,intWorkTime,intID)
{
DWORDdwThreadID;
if(g_NumPerson>=MAX_PERSON)
returnfalse;
Person*pPerson=&g_Persons[g_NumPerson];
pPerson->m_nID=ID;
pPerson->m_nStartTime=StartTime;
pPerson->m_nWorkTime=WorkTime;
pPerson->m_nType=WRITER;
g_NumPerson++;
//创建一个新的线程
pPerson->m_hThread=
CreateThread(NULL,0,WriterProc,(LPVOID)pPerson,0,&dwThreadID);
if(pPerson->m_hThread==NULL)
returnfalse;
returntrue;
}