1、操作系统原理课程设计读者写者问题的实现*实践教学* 计算机与通信学院2012年秋季学期操作系统原理课程设计题 目: 读者-写者问题的实现 专业班级: 姓 名: 学 号: 指导教师: 成 绩: 目录摘 要 21 设计思想 32 各模块的伪码算法 43. 函数关系调用图 64 程序测试结果 7设计总结 10参考文献 11致 谢 12摘 要 本设计的读者写者问题,是指一些进程共享一个数据区。数据区可以使一个文件、一块内存空间或者一组寄存器。Reader进程只能读数据区中的数据,而writer进程必须与其他进程互斥地访问共享对象的同步问题。 读者写者问题可以这样的描述, 有一群写者和一群读者, 写者在
2、写同一本书, 读者也在读这本书, 多个读者可以同时读这本书。但是,只能有一个写者在写书, 并且,读者必写者优先,也就是说,读者和写者同时提出请求时,读者优先。当读者提出请求时需要有一个互斥操作, 另外, 需要有一个信号量S来确定当前是否可操作。 本设计方案就是通过利用记录型信号量对读者写者问题的解决过程进行模 拟演示,形象地阐述记录型信号量机制的工作原理。关键词:共享对象,互斥,同步,信号量1 设计思想本设计借助C语言实现进程同步和互斥的经典问题-读者写者问题,用高级语言编写和调试一个进程同步程序,以加深对进程同步机制的理解。通过用C语言模拟进程同步实现,加深理解有关进程同步和互斥机制的概念及
3、P、V操作的应用。学生通过该题目的设计过程,掌握读者、写者问题的原理、软件开发方法并提高解决实际问题的能力。在 Windows环境下,创建一个包含n个线程的控制台进程。用这n个线每个线程按相应测试数据文件的要求,进行读写操作。程来表示 n 个读者或写者。请用信号量机制分别实现读者优先和写者优先的读者-写者问题。将所有的读者和所有的写者分别放进两个等待队列中,当读允许时就让读者队列释放一个或多个读者,当写允许时,释放第一个写者操作。读者-写者的读写限制(包括读者优先和写者优先) 1)写-写互斥,即不能有两个写者同时进行写操作; 2)读-写互斥,即不能同时有一个读者在读,同时却有一个写者在写; 3
4、)读读允许,即可以有 2 个以上的读者同时读;4)读者优先附加条件:如果一个读者申请进行读操作,同时又有一个读操作正在进行读操作,则该读者可以直接开始读操作; 5)写者优先附加条件:如果一个读者申请进行读操作时已经有一个写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。2 各模块的伪码算法读者优先算法:设置两个互斥信号量:rwmutex 用于写者与其他读者/写者互斥的访问共享数据rmutex 用于读者互斥的访问读者计数器 readcountsemaphore rwmutex=1, rmutex=1;int readcount = 0; reader i /读者进程
5、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); writer j /写者进程 j = 1,2,. do P(rwmutex); 写文件; V(rwmutex); while(1); 写者优先算法:设置三个互斥信号量:rwmutex 用于写者与其他读者/写者互斥的访问共享数据rmutex 用于
6、读者互斥的访问读者计数器readcountnrmutex 用于写者等待已进入读者退出,所有读者退出前互斥写操作semaphore rwmutex= 1,rmutex= 1,nrmutex= 1; int readcount = 0;reader i /读者进程 i=1,2,.doP(rwmutex);P(rmutex);readcount+;if (readcount = 1) P(nrmutex); /有读者进入,互斥写操作V(rmutex);V(rwmutex);/及时释放读写互斥信号量,允许其它读、写进程申请资源读数据;P(rmutex);readcount-;if (readcount
7、 = 0) V(nrmutex); /所有读者退出,允许写更新V(rmutex);while(1);writer j /写者进程 j = 1,2,.doP(rwmutex); / 互斥后续其它读者、写者P(nrmutex); /如有读者正在读,等待所有读者读完写更新;V(nrmutex); /允许后续新的第一个读者进入后互斥写操作V(rwmutex); /允许后续新读者及其它写者while(1);3. 函数关系调用图图1 函数关系图4 程序测试结果测试数据文件包括 n 行测试数据,分别描述创建的 n 个线程是读者还是写者,以及读写操作的开始时间和持续时间.每行测试数据包括四个字段,各字段 间用
8、空格分隔。第一字段为一个正整数,表示线程序号.第二字段表示相应线程 角色,R 表示读者是,W 表示写者。第三字段为一个正数,表示读写操作的开 始时间。线程创建后,延时相应时间 (单位为秒) 后发出对共享资源的读写申请. 第四字段为一个正数,表示读写操作的持续时间。当线程读写申请成功后,开始 对共享资源的读写操作,该操作持续相应时间后结束,并释放共享资源。在读者写者同时在队列中等待申请资时,读者优先调用资源.而且如果一个 读者申请进行读操作时已有另一读者正在进行读操作, 则该读者可直接开始读操 作,即读读允许。图2 进程1、2的测试结果 如图2所示,进程1是W操作,在时间3时进入队列,运行时间是
9、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占用
10、资源,它依然等待,直到进程 3,5 都结束,即进程4在时间12时开始调用资源;进程2是R操作, 在时间16时进入队列,运行时间是5,在它进入时进程4占用资源,它等待资源,当4释放时占用资源后,进程2开始运行;进程6是R操作,在时间17时进入队列,运行时间是7,在它进入时进程2占用资源,它等待进程2释放后最后调用资源。设计总结课程设计是培养学生综合运用所学知识,发现,提出,分析和解决实际问题,锻炼实践能力的重要环节,是对学生实际工作能力的具体训练和考察过程。此次操作系统课程设计,我的感慨颇多,的确,从选题到定稿,从理论到实践,在整整两星期的日子里,我学到很多的东西;同时不仅巩固了以前所学过的知识
11、,而且学到了很多在书本上所没有学到过的知识。通过这次课程设计我懂得了理论与实际相结合的重要性,只有理论知识是远远不够的,所以只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正的服务于社会,从而提高自己的实际动手能力和独立思考的能力。在设计的过程中遇到问题,可以说是困难重重,难免会遇到过各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固。因此,在以后的学习中要多下苦功,加强基础知识的学习,并且培养自己的动手实践能力。参考文献1. 汤子瀛,哲凤屏. 计算机操作系统,西安:电子科技大学学出版社,2002年2. 王清,李光明. 计算机
12、操作系统,北京:冶金工业出版社,2003年3月3.孙钟秀等. 操作系统教程. 北京:高等教育出版社,2008年4月4.曾明. Linux操作系统应用教程. 西安: 陕西科学技术出版社,2005年5. 张丽芬,刘利雄. 操作系统实验教程. 北京: 清华大学出版社,2006年6. 孟静.操作系统教程原理和实例分析. 北京:高等教育出版社,2001年7. 周长林. 计算机操作系统教程. 北京:高等教育出版社,2011年12月8. 张尧学. 计算机操作系统教程.北京:清华大学出版社,2006年10月9. 任满杰. 操作系统原理实用教程.北京:电子工业出版社,2006年1月致 谢这次课程设计培养了我耐心
13、、缜密、全面地思考问题的能力,从而加快了问题解决的速度、提高了个人的工作效率,以及锻炼了使问题在短时间内得以解决的品质。我从“纸上谈兵”到可以自己动脑动手分析调试程序,收获不少。首先要感谢学校给我这次实践的机会,给了自己一个舞台。这不仅是对自身的检验,而且增加了我编写代码的功力。还有多亏了老师们从理论到上机亲自指导的辛苦教授,给予了我们最大帮助和全面指导。在这里,尤其感谢我的指导老师朱红蕾老师,你不辞辛苦的给我们耐心指导。在这里,我衷心向你们致谢!最后还要感谢热心的同学们,在我陷入误区的时候,是他们热心的帮助使我摆脱困境。最后衷心感谢所有给予我帮助和指导的老师和同学,没有他们的帮助我的程序也不
14、会完成得这么顺利。源代码:#include #include #include #include #include #include #define MAX_PERSON 100#define READER 0 /读者#define WRITER 1 /写者#define END -1#define R READER#define W WRITER typedef struct _Person HANDLE m_hThread; /定义处理线程的句柄int m_nType; /进程类型(读写)int m_nStartTime; /开始时间int m_nWorkTime; /运行时间int m_
15、nID;/进程号 Person; Person g_PersonsMAX_PERSON; int g_NumPerson = 0;long g_CurrentTime= 0; /基本时间片数int g_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, ; int g_NumOfReading = 0;int g_NumOfWriteRequest = 0; /申请写进程的个数 HANDLE g_hReadSemaphore; /读者信号 HANDLE
16、 g_hWriteSemaphore; /写者信号 bool finished = false; /所有的读完成 /bool wfinished = false; /所有的写完成 void CreatePersonList(int *pPersonList); bool CreateReader(int StartTime,int WorkTime,int ID); bool CreateWriter(int StartTime,int WorkTime,int ID); DWORD WINAPI ReaderProc(LPVOID lpParam);DWORD WINAPI WriterPr
17、oc(LPVOID lpParam);int main() g_hReadSemaphore = CreateSemaphore(NULL,1,100,NULL); /创建信号灯,当前可用的资源数为 1,最大为100 g_hWriteSemaphore = CreateSemaphore(NULL,1,100,NULL); /创建信号灯,当前 可用的资源数为 1,最大为100CreatePersonList(g_PersonLists); / 创建所有的读者和写者 printf(Created all the reader and writern.n); g_CurrentTime = 0;
18、while(true) g_CurrentTime+; Sleep(300); / 300 ms printf(CurrentTime = %dn,g_CurrentTime); if(finished) return 0; / return 0; void CreatePersonList(int *pPersonLists) int i=0; int *pList = pPersonLists; bool Ret; while(pList0 != END) switch(pList1) case R: Ret = CreateReader(pList2,pList3,pList0); /3
19、51,w452,523,654 break; case W: Ret = CreateWriter(pList2,pList3,pList0); break; if(!Ret) printf(Create Person %d is wrongn,pList0); pList += 4; / move to next person list DWORD WINAPI ReaderProc(LPVOID lpParam) /读过程 Person *pPerson = (Person*)lpParam; / wait for the start time while(g_CurrentTime !=
20、 pPerson-m_nStartTime) printf(Reader %d is Requesting .n,pPerson-m_nID); printf(nn*n); / wait for the write request WaitForSingleObject(g_hReadSemaphore,INFINITE); if(g_NumOfReading=0) WaitForSingleObject(g_hWriteSemaphore,INFINITE); g_NumOfReading+; ReleaseSemaphore(g_hReadSemaphore,1,NULL); pPerso
21、n-m_nStartTime = g_CurrentTime;printf(Reader %d is Reading the Shared Buffer.n,pPerson-m_nID); printf(nn*n); while(g_CurrentTime m_nStartTime + pPerson-m_nWorkTime) printf(Reader %d is Exit.n,pPerson-m_nID); printf(nn*n); WaitForSingleObject(g_hReadSemaphore,INFINITE); g_NumOfReading-; if(g_NumOfRea
22、ding = 0) ReleaseSemaphore(g_hWriteSemaphore,1,NULL);/此时没有读者,可以写 ReleaseSemaphore(g_hReadSemaphore,1,NULL); if(pPerson-m_nID = 4) finished = true; /所有的读写完成 ExitThread(0); return 0; DWORD WINAPI WriterProc(LPVOID lpParam) Person *pPerson = (Person*)lpParam; / wait for the start time while(g_CurrentTi
23、me != pPerson-m_nStartTime) printf(Writer %d is Requesting .n,pPerson-m_nID); printf(nn*n); WaitForSingleObject(g_hWriteSemaphore,INFINITE); / modify the writers real start time pPerson-m_nStartTime = g_CurrentTime; printf(Writer %d is Writting the Shared Buffer.n,pPerson-m_nID); while(g_CurrentTime
24、 m_nStartTime + pPerson-m_nWorkTime) printf(Writer %d is Exit.n,pPerson-m_nID); printf(nn*n); /g_NumOfWriteRequest-; ReleaseSemaphore(g_hWriteSemaphore,1,NULL); if(pPerson-m_nID = 4) finished = true;/所有的读写完成 ExitThread(0); return 0;bool CreateReader(int StartTime,int WorkTime,int ID) /写过程 DWORD dwTh
25、readID; if(g_NumPerson = MAX_PERSON) return false; Person *pPerson = &g_Personsg_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,&dwT
26、hreadID); if(pPerson-m_hThread = NULL) return false; return true; bool CreateWriter(int StartTime,int WorkTime,int ID) DWORD dwThreadID; if(g_NumPerson = MAX_PERSON) return false; Person *pPerson = &g_Personsg_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) return false; return true;
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1