版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、实验内容 1、定义一个数据缓存buffer及用于实现同步互斥的信号量。 2、定义一个读者函数:l 当有写者在占用buffer时,读者应该等待,直到写者不再使用该buffer。l 当有其他读者在占用buffer时,读者可对buffer进行读取操作。l 当buffer中有数据时,则从其中读取一个数据,并显示然后退出。l 当buffer中没有数据时,应等待,直到buffer中有数据可读。 3、定义一个写者函数l 当有读者在占用buffer时,写者应该等待,直到所有的读者都退出为止。l 当有其他写者占用buffer时,该写者应该等待,直到占用buffer的写者退出为止。l 当buffer有空闲时,写者
2、应该在buffer中写入一个数据并退出。l 当buffer满时,写者应该等待,直到buffer有空闲为止。 4、定义主函数,在其中可以任意创建读者与写者。l 可根据用户输入创建读者或写者进程(线程)。 5、用户界面2. 写者:开始读出的内容:1. 读者:开始结束21读者队列等待结束写出的内容:Hello world !结束实验当堂所要完成事情列表:1. 调试程序使其在读者优先模式下可以运行并且能实现基本的功能得出正确的结果:能够实现读写互斥,写写互斥,读读不互斥,一个进程结束能够唤醒等待队列中的进程(先读者队列后写着队列)2. 根据实验要求完善功能:由用户决定写者向缓冲区中写入的内容,读者能够
3、读出并显示出来;当缓冲区中没有数据时,读者要等待,直到缓冲区中有数据才能读3. 根据“读者优先”加以改变,增加一个“写者优先”模式,并且由用户来选择模式源代码:#include<stdio.h>#include<stdlib.h>int rcount=0;/正在读的读者数量int wcount=0;/写者队列中等待写操作的写者数量int read_id=0;/读进程号int write_id=0;/写进程号int w=1;/读写互斥信号量char temp300 = '0'int choice; /用户选择读者优先OR写者优先int sign; /标识t
4、emp空的信号量 0表示temp空void WFwakeup();void RFwakeup();struct rqueue/读者等待队列int readers200;int index;rq;struct wqueue/写者等待队列int writers200;int index;wq;/*void first() /初始化int i;rq.index = 0;wq.index = 0;for(i = 0;i<20;i+)rq.readersi = 0;wq.writersi = 0;*/*读进程读操作void read()int i = 0;read_id+;if(rcount =
5、0)/当前没有读进程在读 可能有写进程在写 可能CPU空闲if(w=1) /如果CPU空闲,读者拿到CPUw-;/ 相当于一个P操作rcount+;if(temp0 = '0')sign = 0;if(choice = 1)rq.readersrq.index+=read_id;/将读者进程加入等待队列RFwakeup();return;elserq.readersrq.index+=read_id;/将读者进程加入等待队列WFwakeup();return;/ifprintf("读者%d正在读n",read_id);for(i = 0;i < 300
6、;i+)/读取temp内容 即写者写的内容if(tempi = '0')printf("n");return;/ifprintf("%c",tempi);/for/ifelse/写者线程正在执行printf("!有写者在写不能读!n");rq.readersrq.index+=read_id;/将读者进程加入等待队列/else/ifelse/rcount !=1 则知道当前已经有读者在读,读读不互斥,则这个读者可以直接进来了读printf("读者%d正在读n",read_id);for(i = 0;
7、i < 300;i+) if(tempi = '0')printf("n");return;printf("%c",tempi);/for/else/*写进程写操作void write()write_id+;if(w = 0)if(rcount != 0 )/有读者进程在执行printf("!有读者在读不能写!n");wq.writerswq.index+=write_id;/将写者进程加入等待队列wcount+;return;if(rcount = 0 )/rcount = 0则当前无读者,但w = 0,所以有
8、写者在写printf("!有写者在写不能写!n");wq.writerswq.index+=write_id;/将写者进程加入等待队列wcount+;return;if(w = 1)w-;printf("写者%d正在写n请输入要写的内容",write_id); scanf("%s",temp);/while/if/*读者优先时唤醒进程void RFwakeup()int i = 0;int j = 0;int m,n;m = rq.index;/n = wq.index;if(rcount = 0)/当前无读进程,是写者在写 -停止运
9、行写进程bool reader_wait=false; w=1;printf("写者已经写完n");sign = 1;/temp中已经有内容 要置1for(i=0;i<=m;i+)/index为当前读者队列中的等待进程数if(rq.readersi!=0)reader_wait=true; /确实有读者在等待printf("等待的读者%d正在读n",rq.readersi);w = 0;for(j = 0;j < 300;j+)if(tempj = '0')printf("n");break;/ifprin
10、tf("%c",tempj);/forrq.readersi=0;rcount+;rq.index-;/if/forif(!reader_wait)/没有读者等待,看是否有写者等待for(int i=0;i<=wq.index;i+)/检查写者等待队列if(wq.writersi!=0)w = 0;printf("等待的写者%d正在写n请输入要写入的内容",wq.writersi);scanf("%s",temp);wq.writersi=0;wcount-;break;/if/for/if/return;/ifelse/rco
11、unt != 0读者正在读,stop读此时若有等待必为写者rcount=0;w = 1;if(sign = 0)printf("缓冲区空 等待写者n");return;elseprintf("读者已经读完n");for(int i=0;i<=wq.index;i+)/检查写者等待队列if(wq.writersi!=0)w = 0;printf("等待的写者%d正在写n请输入要写入的内容",wq.writersi);scanf("%s",temp);wq.writersi=0;wcount-;break;/if
12、/for/else/*写者优先唤醒void WFwakeup()int i = 0;int j = 0;int m,n;m = rq.index;/n = wq.index;if(rcount = 0)/当前无读进程,是写者在写 -停止运行写进程bool writer_wait=false; w=1;printf("写者已经写完n");sign = 1;/temp中已经有内容 要置1for(i=0;i<=wq.index;i+)/index为当前写者队列中的等待进程数if(wq.writersi!=0)writer_wait=true; /确实有写者在等待printf
13、("等待的写者%d正在写n 请输入要写的内容n",wq.writersi);w = 0;scanf("%s",temp);wq.writersi=0;wcount-;break;if(!writer_wait)/没有xie者等待,看是否有du者等待for(int i=0;i<=m;i+)/检查写者等待队列if(rq.readersi!=0)w = 0;printf("等待的读者%d正在读n",rq.readersi);for(j = 0;j < 300;j+)if(tempj = '0')printf(&q
14、uot;n");rq.index-;break;/ifprintf("%c",tempj);/forrq.readersi=0;rcount+;/if/for/if/return;/ifelse/rcount != 0读者正在读,stop读此时若有等待必为写者rcount=0;w = 1;printf("读者已经读完n");for(int i=0;i<=wq.index;i+)/检查写者等待队列if(wq.writersi!=0)w = 0;printf("等待的写者%d正在写n请输入要写入的内容",wq.writer
15、si);scanf("%s",temp);wq.writersi=0;wcount-;break;/if/forvoid menu1()char i;printf(" 1-创建读者进程n 2-创建写者进程n 3-结束当前执行的进程n 4-退出程序n");printf("*n");doprintf("当前队列中有读者: %d个 写者: %d个n",rq.index,wcount);printf("*n");printf(" ->");scanf("%s"
16、;,&i);switch(i)case '1':read();break;case '2':write();break;case '3':RFwakeup();break;case '4':exit(0);default:printf("输入错误请重新输入n");while(true);void menu2()char i;printf(" 1-创建读者进程n 2-创建写者进程n 3-结束当前执行的进程n 4-退出程序n");printf("*n");doprin
17、tf("当前队列中有读者: %d个 写者: %d个n",rq.index,wcount);printf("*n");printf(" ->");scanf("%s",&i);switch(i)case '1':read();break;case '2':write();break;case '3':WFwakeup();break;case '4':exit(0);default:printf("输入错误请重新输入n"
18、);while(true);void main()printf("*n");printf(" 20092104实验一n 1.读者优先n 2.写者优先n");scanf("%d",&choice);while(1)if(choice = 1)menu1();if(choice = 2)menu2();if(choice != 1 && choice != 2)printf("输入错误请重新输入n");scanf("%d",&choice);实验流程图:开始退出写者优
19、先读者优先结束写者优先唤醒读者优先唤醒写操作读操作是否有读者在读有写者 读者入队是否有读者在读NYNNCPU是否空闲有读者 写者入队YCpu是否空闲进行读操作YYN进行写操作缓冲区是否为空读操作N有写者,写操作入队Y入读者等待队列调用读者优先唤醒读者优先唤醒Y当前有无读者在读N有无读者等待NY读者出队进行读操作直到读者队空有无写者等待YN进行写操作N缓冲区是否为空返回Y有读者说明若有等待必为写者写者优先唤醒Y当前有无读者在读N有无写者等待NY写者出队进行写操作直到写者队空有无读者等待Y进行读操作直到读者队列为空N写者队列是否为空返回YN进行写操作直到写者队列为空核心部分设计思路:分别用两个队列
20、来存放等待的读者进程和写者进程,一个进程结束后就要将因他阻塞的进程唤醒,如果是读者优先,则先检查读者进程,如果发现读者进程不为空,就进行读操作,直到读者进程为空,才进行写操作;同理,如果是写者优先,则先检查写进程,如果发现写者进程不为空,就进行写操作,直到写者进程为空,才进行读操作。读写互斥:只有当互斥信号量w = 1并且当前读者数为0时,才可以进行写操作,对于读进程,w = 1且当前读者数为0时,第一个读进程进行读操作,当当前读者数大于0时,不用判断互斥信号量w而直接进行读操作。对缓冲区为空的情况,如果缓冲区为空时进行读操作,则会设置一个信号量标志缓冲区为空sign = 0,不可以进行读操作
21、,释放出CPU,调用唤醒函数唤醒写进程,此时会将此进程放入读者进程等待队列中等待写者来写数据再进行读操作,写者写完数据,缓冲区不空时,将标志置为缓冲区不空sign = 1。编译过程中遇到的问题:1. 编译过程中出现的一个很大的错误就是在构造队列的时候给变量index赋值了,系统提示错误解决:取消赋值,编写了一个初始化函数进行初始化,后来发现不初始化也没用什么问题,就注释掉了。2. 刚开始还会出现一些括号不匹配的错误,在后来的程序完善过程中,尽量给后括号做一个注释进行标识。运行过程中遇到的问题:1. 不能接受非法字符,如果输入非法字符就会进入死循环,但是在switch外明明有检查语句。解决:通过单步跟踪,发现检查语句并没有起到作用,于是调整了一下结构,将检查语句放到switch里,既起到了检查的作用,同时也减少了代码量。2. 在读者进行读取数据时,总是会在读取完写者写的内容的后面出现一个小a。解决:也是通过单步跟踪,发现是判空和输出的顺序问题,如果先输出后判空的话,会多进行一次循环,导致输出一个小a,但是现在还是不太明白为什么多输出的是小a。3. 当缓冲区为空的时候创建了
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年蛋炒午餐肉食品加工机维修(加工机故障排除)试题及答案
- 2025年高职第一学年(家政服务)高端护理阶段测试题及答案
- 2025年高职(应用化工技术)化工仪表试题及答案
- 2025年大学社会研究方法(调研数据处理)试题及答案
- 2025年中职机械类(机械制图基础)试题及答案
- 2025年中职非金属材料(材料加工技术)试题及答案
- 2025年高职第二学年(康复治疗技术)言语治疗技术试题及答案
- 2025年高职电子信息工程技术(电子信息工程应用)试题及答案
- 2025年中职职业卫生技术与管理(职业卫生管理)期末试题
- 2025年高职(药事管理与法规)法规应用单元测试试题及答案
- 广东省花都亚热带型岩溶地区地基处理与桩基础施工技术:难题破解与方案优化
- 生鲜乳安全生产培训资料课件
- 基于知识图谱的高校学生岗位智能匹配平台设计研究
- GB 4053.3-2025固定式金属梯及平台安全要求第3部分:工业防护栏杆及平台
- 2026年《必背60题》高校专职辅导员高频面试题包含详细解答
- 2026年八年级生物上册期末考试试卷及答案
- 工程顾问协议书
- 2026年沃尔玛财务分析师岗位面试题库含答案
- GA 1016-2012枪支(弹药)库室风险等级划分与安全防范要求
- 220kv输电线路工程施工组织设计
- (完整)中考英语常考的500个高频词汇
评论
0/150
提交评论