淮北师范大学程序设计课程设计采用“读写平等”策略的“读者--写者”问题学院计算机科学与技术专业计算机科学与技术(师范)学号***********学生姓名***指导教师姓名***2012年6月16日1一、设计目的与内容课程设计的目的:操作系统课程设计是计算机专业重要的教学环节,它为学生提供了一个既动手又动脑,将课本上的理论知识和实际有机的结合起来,独立分析和解决问题的机会。进一步巩固和复习操作系统的基础知识。培养学生结构化程序、模块化程序设计的方法和能力。提高学生调试程序的技巧和软件设计的能力。提高学生分析问题、解决问题以及综合利用C语言进行程序设计的能力。设计内容:用高级语言编写和调试一个采用“读写平等”策略的“读者—写者”问题的模拟程序。设计的要求:1.读者与写者至少包括ID、进入内存时间、读写时间三项内容,可在界面上进行输入。2.读者与写者均有两个以上,可在程序运行期间进行动态增加读者与写者。3.可读取样例数据(要求存放在外部文件中),进行读者/写者、进入内存时间、读写时间的初始化。4.要求将运行过程用可视化界面动态显示,可随时暂停,查看阅览室中读者/写者数目、读者等待队列、读写时间、等待时间。5.读写策略:读写互斥、写写互斥、读写平等(严格按照读者与写者到达的顺序进入阅览室,有写着到达,则阻塞后续到达的读者;有读者到达,则阻塞后续到达的写者)。有一个被许多进程共享的数据区,这个数据区可以是一个文件,或者主存的一块空间,甚至可以是一组处理器寄存器。有一些只读取这个数据2区的进程(reader)和一些只往数据区中写数据的进程(writer)。以下假设共享数据区是文件。这些读者和写者对数据区的操作必须满足以下条件:读—读允许;读—写互斥;写—写互斥。这些条件具体来说就是:(1)任意多的读进程可以同时读这个文件;(2)一次只允许一个写进程往文件中写;(3)如果一个写进程正在往文件中写,禁止任何读进程或写进程访问文件;(4)写进程执行写操作前,应让已有的写者或读者全部退出。这说明当有读者在读文件时不允许写者写文件。二、算法的基本思想创建三个线性链表,分别为head1、head2、head3。head1写入序列,head2为就绪序列,head3为执行序列。其中head1用来存放输入进去的读者和写者的信息,head2根据读入内存的时间将head1中的读者写者的信息进行排序,并将排完序的读者与写者信息存在head2中,把head2的内容调入到执行序列head3中,从而执行要求的内容。三、主要功能模块流程图3四、系统测试(列出对于给定的输入所产生的输出结果。只写出自己所做功能测试结果)开始Jiuxu(inti)typereader()rwriter()wruntime++runtime==needtime离开head3head1==Null&head2==Null&head3==NullYNi++Y结束4文件为文本文件。文件内容为:5(表示进程数)1r72(表示进程名,进程类型,进程开始时间,进程运行时间)2w23(表示进程名,进程类型,进程开始时间,进程运行时间)3r34(表示进程名,进程类型,进程开始时间,进程运行时间)4r53(表示进程名,进程类型,进程开始时间,进程运行时间)5w64(表示进程名,进程类型,进程开始时间,进程运行时间)程序运行实例如下:1.选择2,运行界面如下:52.选择3,运行界面如下:3.在执行过程中按下s可以暂停进程的执行。64.在进程暂停的情况下,按下a可以增加进程。五、结论程序运行后,可以通过手动输入进程和文件读取进程,并执行读者与写者在公平竞争下的同步进程问题,另外可以实现进程的可视化显示、暂停和动态增加最后退出。完成任务书的要求。7六、源程序及系统文件使用说明#includestdio.h#includestdlib.h#includeconio.h#includewindows.hintWmutex=1;//互斥读写的信号量intreadcount=0;//读者数目voidinput();voidmain();structprocess{intID;//进程序号chartype;//进程类别(判断是读者还是写者)intstarttime;//进程开始时间intneedtime;//进程读写需要的时间intruntime;//进程在内存中已运行的时间structprocess*next;};process*head1=NULL,*head2=NULL,*head3=NULL;voidchoose()//选择{inta;process*p,*q;q=head1=(process*)malloc(sizeof(process));FILE*fp;scanf(%d,&a);switch(a){case1://手动输入8inti,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=head1;head1=head1-next;p-next=NULL;free(p);break;case2://文件读入if((fp=fopen(file.txt,r))==NULL){printf(文件打开失败!\n);system(pause);system(cls);main();9}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=head1;head1=head1-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;10fscanf(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=head1;head1=head1-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();11}}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=head1;q=head2;intt=0;if(head2==NULL){q=head2=(process*)malloc(sizeof(process));q-next=NULL;t=1;}else{while(q-next!=NULL){q=q-next;}}12j=(process*)malloc(sizeof(process));j-next=head1;while(head1-starttime==i){q-next=head1;head1=head1-next;q=q-next;q-next=NULL;j-next=head1;if(head1==NULL)break;}p=head1;while(p!=NULL){if(p-starttime==i){k=j;while(k-next!=p){k=k-next;}k-next=p-next;q-next=p;q=q-next;p=p-next;q-next=NULL;}else{p=p-next;}}13head1=j-next;j-next=NULL;free(j);if(t==1){p=head2;head2=head2-next;p-next=NULL;free(p);}}intwait(int&a){a--;if(a0){return0;}return1;}voidsignal(int&a){a++;}voidreader()//读写平等下的读者信息{process*p;intt=0;p=head3;if(head3==NULL){14p=head3=(process*)malloc(sizeof(process));p-next=NULL;t=1;}else{while(p-next!=NULL){p=p-next;}}if(readcount0){p-next=head2;head2=head2-next;p=p-next;p-next=NULL;readcount++;}if((readcount==0)&&(wait(Wmutex)==1)){p-next=head2;head2=head2-next;p=p-next;p-next=NULL;readcount++;}elseWmutex++;if(t==1){p=head3;head3=head3-next;p-next=NULL;15free(p);}}voidwriter()//读写平等下的写者信息{if((wait(Wmutex)==1)&&(head3==NULL)){head3=head2;head2=head2-next;head3-next=NULL;}elseWmutex++;}voidadd(inti)//动态增加{process*p,*q;inta;p