淮北师范大学课程设计采用读写平等策略的读者写者问题学号:姓名:专业:指导教师:日期:目录第1部分课设简介....................................31.1课程设计题目..................................31.2课程设计目的..................错误!未定义书签。1.3课程设计内容..................................31.4课程设计要求..................................41.5时间安排.......................................4第2部分实验原理分析................................42.1问题描述......................................42.2算法思想......................................52.3主要功能模块流程图............................5第3部分主要的功能模块..............................63.1数据结构......................................63.2测试用例及运行结果............................7第4部分源代码......................................7第5部分总结及参考文献.............................225.1总结.........................................225.2参考文献....................................23第1部分课设简介1.1课程设计题目采用读写平等策略的读者写者问题1.2课程设计目的操作系统课程设计是计算机专业重要的教学环节,它为学生提供了一个既动手又动脑,将课本上的理论知识和实际有机的结合起来,独立分析和解决实际问题的机会。1)进一步巩固和复习操作系统的基础知识。2)培养学生结构化程序、模块化程序设计的方法和能力。3)提高学生调试程序的技巧和软件设计的能力。4)提高学生分析问题、解决问题以及综合利用C语言进行课程设计的能力。1.3课程设计内容用高级语言编写和调试一个采用“读写平等”策略的“读者--写者”问题的模拟程序。1.4课程设计要求1)读者与写者至少包括ID、进入内存时间、读写时间三项内容,可在界面上进行输入。2)读者与写者均有两个以上,可在程序运行期间进行动态增加读者与写者。3)可读取样例数据(要求存放在外部文件中),进行读者/写者、进入内存时间、读写时间的初始化。4)要求将运行过程用可视化界面动态显示,可随时暂停,查看阅览室中读者/写者数目、读者等待队列、读写时间、等待时间。5)读写策略:读写互斥、写写互斥、读写平等(严格按照读者与写者到达的顺序进入阅览室,有写着到达,则阻塞后续到达的读者;有读者到达,则阻塞后续到达的写者)。1.5时间安排1)分析设计贮备阶段(1天)2)编程调试阶段(7天)3)写课程设计报告、考核(2天)第2部分实验原理分析2.1问题描述有一个被许多进程共享的数据区,这个数据区可以是一个文件,或者主存的一块空间,甚至可以是一组处理器寄存器。有一些只读取这个数据区的进程reader和一些只往数据区中写数据的进程writer以下假设共享数据区是文件。这些读者和写者对数据区的操作必须满足以下条件:读—读允许;读—写互斥;写—写互斥。这些条件具体来说就是:1)任意多的读进程可以同时读这个文件;2)一次只允许一个写进程往文件中写;3)如果一个写进程正在往文件中写,禁止任何读进程或写进程访问文件;4)写进程执行写操作前,应让已有的写者或读者全部退出。这说明当有读者在读文件时不允许写者写文件。2.2算法思想三个线性链表,分别为h1、h2、h3。h1为写入序列,h2为就绪序列,h3为执行序列。其中h1用来存放输入进去的读者和写者的信息,h2根据读入内存的时间将h1中的读者写者的信息进行排序,并将排完序的读者与写者信息存在h2中,把h2的内容调入到执行序列h3中,从而执行要求的内容。2.3主要功能模块流程图第3部分主要的功能模块3.1数据结构主要的数据结构及数据:开始ready(inti)typereader()rwriter()wruntime++runtime==needtime离开h3h1==Null&h2==Null&h3==NullYNi++Y结束intWmutex=1;//互斥读写的信号量intreadcount=0;//读者数目structprocess//进程结构体{intID;//进程序号chartype;//进程类别(判断是读者还是写者)intstarttime;//进程开始时间intneedtime;//进程读写需要的时间intruntime;//进程在内存中已运行的时间structprocess*next;};process*h1=NULL,*h2=NULL,*h3=NULL;//三个链表函数成员:voidinput()//输入信息函数voidmain()//主函数voidchoose()//选择函数voidready(inti)//进入就绪队列函数intwait(int&a)//等待队列函数voidreader()//读写平等下的读者信息函数voidwriter()//读写平等下的写者信息函数voidadd(inti)//动态增加函数voidprint(inti)//输出函数voidleave()//离开执行队列3.2测试用例及运行结果运行程序进入界面后,选择1,运行界面如图1-1;选择2,运行完后查看文件显示如图1-2;选择3查看信息,运行界面如图1-3;在执行过程中按下s可以暂停进程的执行,在进程暂停的情况下,按下a可以增加进程,运行结果如图1-4所示。图1-1图1-2图1-3图1-4第4部分源代码#includestdio.h#includestdlib.h#includeconio.h#includewindows.hintWmutex=1;//互斥读写的信号量intreadcount=0;//读者数目voidinput();voidmain();structprocess{intID;//进程序号chartype;//进程类别(判断是读者还是写者)intstarttime;//进程开始时间intneedtime;//进程读写需要的时间intruntime;//进程在内存中已运行的时间structprocess*next;};process*h1=NULL,*h2=NULL,*h3=NULL;voidchoose()//选择{inta;process*p,*q;q=h1=(process*)malloc(sizeof(process));FILE*fp;scanf(%d,&a);switch(a){case1://手动输入inti,j;printf(\t\t输入进程数:);fp=fopen(file.txt,w+);scanf(%d,&i);fprintf(fp,%d\n,i);for(j=1;i0;i--,j++){p=(process*)malloc(sizeof(process));q-next=p;printf(\t\t第%d个进程:\n,j);printf(\t\t进程序号\t读或写\t\t开始时间\t执行时间\n\t\t);scanf(%d%c%d%d,&p-ID,&p-type,&p-starttime,&p-needtime);fprintf(fp,%d%c%d%d\n,p-ID,p-type,p-starttime,p-needtime);printf(\n);p-runtime=0;q=q-next;p-next=NULL;}fclose(fp);p=h1;h1=h1-next;p-next=NULL;free(p);break;case2://文件读入if((fp=fopen(file.txt,r))==NULL){printf(文件打开失败!\n);system(pause);system(cls);main();}fscanf(fp,%d,&i);for(j=1;i0;i--,j++){p=(process*)malloc(sizeof(process));q-next=p;fscanf(fp,%d%c%d%d,&p-ID,&p-type,&p-starttime,&p-needtime);p-runtime=0;q=q-next;p-next=NULL;}fclose(fp);p=h1;h1=h1-next;p-next=NULL;free(p);break;case3:intk;if((fp=fopen(file.txt,r))==NULL){printf(文件打开失败!\n);system(pause);system(cls);main();}printf(\t\t进程序号\t读或写\t\t开始时间\t执行时间\n);fscanf(fp,%d,&i);k=0;for(j=0;i0;i--,j++){p=(process*)malloc(sizeof(process));q-next=p;fscanf(fp,%d%c%d%d,&p-ID,&p-type,&p-starttime,&p-needtime);if(p-type=='r'||p-type=='R'){k++;}printf(\t\t%d\t\t%c\t\t%d\t\t%d\n,p-ID,p-type,p-starttime,p-needtime);p-runtime=0;q=q-next;p-next=NULL;}j=j-k;printf(\t\t读者数目:);printf(\t%d\n,k);printf(\t\t写者数目:);printf(\t%d\n,j);fclose(fp);p=h1;h1=h1-next;p-next=NULL;free(p);system(pause);system(cls);main();break;case4:exit(0);default:printf(\t\t您输入的有错误,请重新输入:\n);system(pause);system(cls);main();}}voidinput()//输入函数{printf(\t\t***********读写平等策略*********\n);printf(\t\t\t1.请输入进程信息\n);printf(\t\t\t2.文件载入进程信息\n);printf(\t\t\t3.查看进程信息\n);printf(\t\t\t4.退出\n);printf(\t\t************************************\n);printf(\t\t请选择:);choose();}voidready(inti)//进入就绪队列{process*p,*q,*j,*k;p=h1;q=h2;intt=0;if(h2==NULL){q=h2=(process*)malloc(sizeof(process));q-next=NULL;t=1;}else{while(q-next!=NULL){q=q-next;}}j=(process*)malloc(sizeof(process));j-next=head1;while(h1-starttime==i){q-next=head1;h1=h1-next;q=q-next;q-next=NULL;j-next=head1;if(h1==NULL)break;}p=h1;while(p!=N