还剩12页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
实验内容
1、定义一个数据缓存buffer及用于实现同步互斥的__量
2、定义一个读者函数当有写者在占用buffer时,读者应该等待,直到写者不再使用该buffer当有其他读者在占用buffer时,读者可对buffer进行读取操作当buffer中有数据时,则从其中读取一个数据,并显示然后退出当buffer中没有数据时,应等待,直到buffer中有数据可读
3、定义一个写者函数当有读者在占用buffer时,写者应该等待,直到所有的读者都退出为止当有其他写者占用buffer时,该写者应该等待,直到占用buffer的写者退出为止当buffer有空闲时,写者应该在buffer中写入一个数据并退出当buffer满时,写者应该等待,直到buffer有空闲为止
4、定义主函数,在其中可以任意创建读者与写者可根据用户输入创建读者或写者进程线程
5、用户界面实验当堂所要完成事情列表
1.调试程序使其在读者优先模式下可以运行并且能实现基本的功能得出正确的结果能够实现读写互斥,写写互斥,读读不互斥,一个进程结束能够唤醒等待队列中的进程(先读者队列后写着队列)
2.根据实验要求完善功能由用户决定写者向缓冲区中写入的内容,读者能够读出并显示出来;当缓冲区中没有数据时,读者要等待,直到缓冲区中有数据才能读
3.根据“读者优先”加以改变,增加一个“写者优先”模式,并且由用户来选择模式源代码#includestdio.h#includestdlib.hintrcount=0;//正在读的读者数量intwcount=0;//写者队列中等待写操作的写者数量intread_id=0;//读进程号intwrite_id=0;//写进程号intw=1;//读写互斥__量chartemp
[300]={\0};intchoi__;//用户选择读者优先OR写者优先intsign;//标识temp空的__量0表示temp空voidWFwakeup;voidRFwakeup;structrqueue{//读者等待队列intreaders
[200];intindex;}rq;structwqueue{//写者等待队列intwriters
[200];intindex;}wq;/*voidfirst{//初始化inti;rq.index=0;wq.index=0;fori=0;i20;i++{rq.readers[i]=0;wq.writers[i]=0;}}*///*******************************************读进程读操作voidread{inti=0;read_id++;ifrcount==0{//当前没有读进程在读可能有写进程在写可能CPU空闲ifw==1{//如果CPU空闲,读者拿到CPUw--;//相当于一个P操作rcount++;iftemp
[0]==\0{sign=0;ifchoi__==1{rq.readers[rq.index++]=read_id;//将读者进程加入等待队列RFwakeup;return;}else{rq.readers[rq.index++]=read_id;//将读者进程加入等待队列WFwakeup;return;}}//ifprintf读者%d正在读\nread_id;fori=0;i300;i++{//读取temp内容即写者写的内容iftemp[i]==\0{printf\n;return;}//ifprintf%ctemp[i];}//for}//ifelse{//写者线程正在执行printf!有写者在写不能读!\n;rq.readers[rq.index++]=read_id;//将读者进程加入等待队列}//else}//ifelse{//rcount!=1则知道当前已经有读者在读,读读不互斥,则这个读者可以直接进来了读printf读者%d正在读\nread_id;fori=0;i300;i++{iftemp[i]==\0{printf\n;return;}printf%ctemp[i];}//for}//else}//***************************写进程写操作voidwrite{write_id++;ifw==0{ifrcount!=0{//有读者进程在执行printf!有读者在读不能写!\n;wq.writers[wq.index++]=write_id;//将写者进程加入等待队列wcount++;return;}ifrcount==0{//rcount==0则当前无读者,但w=0,所以有写者在写printf!有写者在写不能写!\n;wq.writers[wq.index++]=write_id;//将写者进程加入等待队列wcount++;return;}}ifw==1{w--;printf写者%d正在写\n请输入要写的内容write_id;scanf%stemp;//while}//if}//************************读者优先时唤醒进程voidRFwakeup{inti=0;intj=0;intmn;m=rq.index;//n=wq.index;ifrcount==0{//当前无读进程,是写者在写--》停止运行写进程boolreader_wait=false;w=1;printf写者已经写完\n;sign=1;//temp中已经有内容要置1fori=0;i=m;i++{//index为当前读者队列中的等待进程数ifrq.readers[i]!=0{reader_wait=true;//确实有读者在等待printf等待的读者%d正在读\nrq.readers[i];w=0;forj=0;j300;j++{iftemp[j]==\0{printf\n;break;}//ifprintf%ctemp[j];}//forrq.readers[i]=0;rcount++;rq.index--;}//if}//forif!reader_wait{//没有读者等待,看是否有写者等待forinti=0;i=wq.index;i++{//检查写者等待队列ifwq.writers[i]!=0{w=0;printf等待的写者%d正在写\n请输入要写入的内容wq.writers[i];scanf%stemp;wq.writers[i]=0;wcount--;break;}//if}//for}//if//return;}//ifelse{//rcount!=0读者正在读,stop读此时若有等待必为写者rcount=0;w=1;ifsign==0{printf缓冲区空等待写者\n;return;}else{printf读者已经读完\n;forinti=0;i=wq.index;i++{//检查写者等待队列ifwq.writers[i]!=0{w=0;printf等待的写者%d正在写\n请输入要写入的内容wq.writers[i];scanf%stemp;wq.writers[i]=0;wcount--;break;}//if}//for}}//else}//******************************************写者优先唤醒voidWFwakeup{inti=0;intj=0;intmn;m=rq.index;//n=wq.index;ifrcount==0{//当前无读进程,是写者在写--》停止运行写进程boolwriter_wait=false;w=1;printf写者已经写完\n;sign=1;//temp中已经有内容要置1fori=0;i=wq.index;i++{//index为当前写者队列中的等待进程数ifwq.writers[i]!=0{writer_wait=true;//确实有写者在等待printf等待的写者%d正在写\n请输入要写的内容\nwq.writers[i];w=0;scanf%stemp;wq.writers[i]=0;wcount--;break;}}if!writer_wait{//没有xie者等待,看是否有du者等待forinti=0;i=m;i++{//检查写者等待队列ifrq.readers[i]!=0{w=0;printf等待的读者%d正在读\nrq.readers[i];forj=0;j300;j++{iftemp[j]==\0{printf\n;rq.index--;break;}//ifprintf%ctemp[j];}//forrq.readers[i]=0;rcount++;}//if}//for}//if//return;}//ifelse{//rcount!=0读者正在读,stop读此时若有等待必为写者rcount=0;w=1;printf读者已经读完\n;forinti=0;i=wq.index;i++{//检查写者等待队列ifwq.writers[i]!=0{w=0;printf等待的写者%d正在写\n请输入要写入的内容wq.writers[i];scanf%stemp;wq.writers[i]=0;wcount--;break;}//if}//for}}voidmenu1{chari;printf1-创建读者进程\n2-创建写者进程\n3-结束当前执行的进程\n4-退出程序\n;printf*******************************************\n;do{printf当前队列中有读者%d个写者%d个\nrq.indexwcount;printf*******************************************\n;printf-----;scanf%si;switchi{case1:read;break;case2:write;break;case3:RFwakeup;break;case4:exit0;default:printf输入错误请重新输入\n;}}whiletrue;}voidmenu2{chari;printf1-创建读者进程\n2-创建写者进程\n3-结束当前执行的进程\n4-退出程序\n;printf*******************************************\n;do{printf当前队列中有读者%d个写者%d个\nrq.indexwcount;printf*******************************************\n;printf-----;scanf%si;switchi{case1:read;break;case2:write;break;case3:WFwakeup;break;case4:exit0;default:printf输入错误请重新输入\n;}}whiletrue;}void__in{printf**************************************************************************\n;printf20092104实验一\n
1.读者优先\n
2.写者优先\n;scanf%dchoi__;while1{ifchoi__==1menu1;ifchoi__==2menu2;ifchoi__!=1choi__!=2{printf输入错误请重新输入\n;scanf%dchoi__;}}}实验流程图NY核心部分设计思路分别用两个队列来存放等待的读者进程和写者进程,一个进程结束后就要将因他阻塞的进程唤醒,如果是读者优先,则先检查读者进程,如果发现读者进程不为空,就进行读操作,直到读者进程为空,才进行写操作;同理,如果是写者优先,则先检查写进程,如果发现写者进程不为空,就进行写操作,直到写者进程为空,才进行读操作读写互斥只有当互斥__量w=1并且当前读者数为0时,才可以进行写操作,对于读进程,w=1且当前读者数为0时,第一个读进程进行读操作,当当前读者数大于0时,不用判断互斥__量w而直接进行读操作对缓冲区为空的情况,如果缓冲区为空时进行读操作,则会设置一个__量标志缓冲区为空sign=0,不可以进行读操作,释放出CPU,调用唤醒函数唤醒写进程,此时会将此进程放入读者进程等待队列中等待写者来写数据再进行读操作,写者写完数据,缓冲区不空时,将标志置为缓冲区不空sign=1编译过程中遇到的问题
1.编译过程中出现的一个很大的错误就是在构造队列的时候给变量index赋值了,系统提示错误解决取消赋值,编写了一个初始化函数进行初始化,后来发现不初始化也没用什么问题,就注释掉了
2.刚开始还会出现一些括号不匹配的错误,在后来的程序完善过程中,尽量给后括号做一个注释进行标识运行过程中遇到的问题
1.不能接受非法字符,如果输入非法字符就会进入死循环,但是在switch外明明有检查语句解决通过单步跟踪,发现检查语句并没有起到作用,于是调整了一下结构,将检查语句放到switch里,既起到了检查的作用,同时也减少了代码量
2.在读者进行读取数据时,总是会在读取完写者写的内容的后面出现一个小a解决也是通过单步跟踪,发现是判空和输出的顺序问题,如果先输出后判空的话,会多进行一次循环,导致输出一个小a,但是现在还是不太明白___多输出的是小a
3.当缓冲区为空的时候创建了n-1个读进程,他们都在等待写进程写数据,然而等写进程写完数据后,这些读进程并没有进行读取,继续创建读进程,就会发现是读进程n在进行读取解决刚开始是以为参数设置问题,后来仔细一想,发现是没有在调用唤醒函数前没有将读进程放入读者等待队列中,于是在调用唤醒函数前,添加将读者进程放入等待队列的语句
4.还出现了不少小错误,例如将ij写错导致读者每次都会读300次用一个字母,没有设置__量sign导致在缓冲区为空的时候还没有进行读操作就会有“读者已经读完”的错误提示等等也有一些原则性错误比如在唤醒函数中,读或者写进程结束后,将__量置1,但是在队列中选择进程进行操作的时候,没有把__量置0,导致了执行唤醒函数后进程不互斥的问题开始的程序中还设置了一些意义不大的变量,比较混乱,后来通过画简单的流程图,将意义不大的变量取消,理清了思路,解决了问题运行过程中的问题出现的问题比较多,但都不是特别大的问题,通过调试分析都得到了解决实验收获与心得这次实验耗时比较多,预习的时候并没有准备特别充分,程序还有很多问题,功能也不没有达到老师的要求实验过程中,一步一步由简到繁,完善程序的同时,问题也出现了不少,通过画简单的流程图,通过单步跟踪,通过分析理解,都得到了解决程序的缺点就是设置的变量过多,后来经过分析和调试,发现很多都是没有必要的,还让程序更加混乱,条理不清楚,后来去掉了不少这次实验让我更加深刻的理解了进程的__量的概念和应用,在不断出现错误,发现错误,改正错误的过程中,对互斥__量有了非常深刻的理解虽然程序的功能还不是很完善,但是自己调试成功的程序就非常有成就感下次实验我会提前做好充分的预习,争取做的更好
2.写者开始读出的内容
1.读者开始结束21读者队列等待结束写出的内容Helloworld!结束开始退出写者优先读者优先结束写者优先唤醒读者优先唤醒写操作读操作是否有读者在读有写者读者入队是否有读者在读NYNYCPU是否空闲有读者写者入队Cpu是否空闲进行读操作YN进行写操作缓冲区是否为空读操作N有写者,写操作入队Y入读者等待队列调用读者优先唤醒读者优先唤醒Y当前有无读者在读N有无读者等待NY读者出队进行读操作直到读者队空有无写者等待YN进行写操作N缓冲区是否为空返回Y有读者说明若有等待必为写者写者优先唤醒Y当前有无读者在读N有无写者等待NY写者出队进行写操作直到写者队空有无读者等待Y进行读操作直到读者队列为空N写者队列是否为空返回YN进行写操作直到写者队列为空。