OS课程设计读者写者.docx
- 文档编号:8500051
- 上传时间:2023-01-31
- 格式:DOCX
- 页数:18
- 大小:187.49KB
OS课程设计读者写者.docx
《OS课程设计读者写者.docx》由会员分享,可在线阅读,更多相关《OS课程设计读者写者.docx(18页珍藏版)》请在冰豆网上搜索。
OS课程设计读者写者
兰州交通大学
操作系统课程设计
课程:
计算机操作系统
题目:
进程同步(读者--写者)
班级:
姓名:
学号:
指导教师:
日期:
2012年12月21日
1题目
进程同步模拟设计——读者和写者问题
2设计概述
2.1问题描述
模拟用信号量机制实现读者和写者问题,即有两组并发进程:
读者和写者,共享一组数据区,进行读写操作,要求任一时刻“写者”最多只允许一个,而“读者”则允许多个。
2.1.1要求
允许多个读者同时执行读操作;
不允许读者、写者同时操作;
不允许多个写者同时操作。
2.1.2读者和写者的相互关系:
2.2采用信号量机制
1)Wmutex表示读写的互斥信号量,初值:
Wmutex=1;
2)公共变量Rcount表示“正在读”的进程数,初值:
Rcount=0;
3)Rmutex:
表示对Rcount的互斥操作,初值:
Rmutex=1。
3课程设计目的及功能
3.1设计目的
通过实验模拟读者和写者之间的关系,了解并掌握他们之间的关系及其原理。
由此增加对进程同步的问题的了解。
具体如下:
1)掌握基本的同步互斥算法,理解读者和写者模型;
2)了解windows中多线程(多进程)的并发执行机制,线程(进程)间的同步和互斥;
3)学习使用windows中基本的同步对象,掌握相应的API。
3.2设计功能
利用模拟用信号量机制实现读者和写者问题:
通过用户控制读进程和写进程,反应读者和写者问题中所涉及的进程的同步与互斥。
4总体设计思想概述
4.1功能流程图
4.2开发平台及源程序的主要部分
本实验用C++语言在VisualC++6.0中编程。
4.3数据结构
intr_num;//读者个数
intw_num;//写者个数
intWmutex=1;//表示允许写或允许读
intRcount=0;//表示正在读的进程数
intRmutex=1;//表示对Rcount的互斥操作
intr[10]={0,0,0,0,0,0,0,0,0,0};//表示读者的状态,1表示正在读
intw[10]={0,0,0,0,0,0,0,0,0,0};//表示写者的状态,1表示正在写
//表示等待队列,0-9表示写者,10时需引入读者的等待队列,-1表示空
intw_wait[11]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
//读者的等待队列,0-9表示对应的读者,-1为空
intr_wait[11]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
4.4模块说明
四组P、V函数:
1)写者进程由3个函数组成
voidwrite_p(inti)//模拟写者对Wmutex的P操作,同时也作为写者进程的入口
voidwrite(inti)//开始写操作
voidwrite_v(inti)//模拟写者对Wmutex的V操作,写操作完成的时候调用
2)读者进程由8个函数组成
voidradd_p(inti)//模拟读之前对Rmutex的P操作,同时也作为读者进程的入口
voidradd(inti)//Rcount加1
voidread_p(inti)//模拟读者对Wmutex的P操作
voidradd_v(inti)//模拟读之前对Rmutex的V操作
voidread(inti)//读
voidrsub_p(inti)//模拟读之后对Rmutex的P操作,读操作完成的时候调用
voidrsub(inti)//Rcount减1
voidread_v(inti)//模拟读者对Wmutex的V操作
voidrsub_v(inti)//模拟读之后对Rmutex的V操作
4.5源程序
#include
#include
#include
#include
usingnamespacestd;
intr_num;//读者个数
intw_num;//写者个数
intWmutex=1;//表示允许写或允许读
intRcount=0;//表示正在读的进程数
intRmutex=1;//表示对Rcount的互斥操作
intr[10]={0,0,0,0,0,0,0,0,0,0};//表示读者的状态,1表示正在读
intw[10]={0,0,0,0,0,0,0,0,0,0};//表示写者的状态,1表示正在写
intw_wait[11]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};//表示等待队列,0-9表示写者,10时需引入读者的等待队列,-1表示空
intr_wait[11]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};//读者的等待队列,0-9表示对应的读者,-1为空
voidwrite_p(inti);//模拟写者对Wmutex的P操作,同时也作为写者进程的入口
voidwrite(inti);//开始写操作
voidwrite_v(inti);//模拟写者对Wmutex的V操作,写操作完成的时候调用
voidradd_p(inti);//模拟读之前对Rmutex的P操作,同时也作为读者进程的入口
voidradd(inti);//Rcount加1
voidread_p(inti);//模拟读者对Wmutex的P操作
voidradd_v(inti);//模拟读之前对Rmutex的V操作
voidread(inti);//读
voidrsub_p(inti);//模拟读之后对Rmutex的P操作,读操作完成的时候调用
voidrsub(inti);//Rcount减1
voidread_v(inti);//模拟读者对Wmutex的V操作
voidrsub_v(inti);//模拟读之后对Rmutex的V操作
//模拟写者对Wmutex的P操作,同时为写者进程也作写的入口
voidwrite_p(inti)
{
Wmutex--;
if(Wmutex<0)//表示如果Wmutex<0,则该写者进入等待队列
{
w_wait[-Wmutex-1]=i;
}
else
write(i);
}
//进行写操作
voidwrite(inti)
{
w[i]=1;
}
//模拟写者对Wmutex的V操作,写操作完成的时候调用
voidwrite_v(inti)
{
w[i]=0;
Wmutex++;
if(Wmutex<=0)//表示如果Wmutex<=0,则从等待队列中选择写者或读者进行操作
{
intk,j;
if((w_wait[0]>=0)&&(w_wait[0] { j=w_wait[0]; for(k=0;k w_wait[k]=w_wait[k+1]; write(j); } else { j=r_wait[0]; for(k=0;k w_wait[k]=w_wait[k+1]; for(k=0;k r_wait[k]=r_wait[k+1]; radd_v(j); } } } //模拟读之前对Rmutex的P操作,同时也作为读者进程的入口 voidradd_p(inti){ Rmutex--; if(Rmutex<0)//表示如果Rmutex<0,则进入等待队列 { r_wait[-Rmutex]=i; } else radd(i); } //对于Rcount加1的控制 voidradd(inti) { Rcount++; if(Rcount==1) read_p(i); else radd_v(i); } //模拟读者对Wmutex的P操作: voidread_p(inti) { Wmutex--; if(Wmutex<0)//表示如果Wmutex<0,则进入等待队列 { w_wait[-Wmutex-1]=10; r_wait[0]=i; } else radd_v(i); } //模拟读之前对Rmutex的V操作 voidradd_v(inti) { Rmutex++; if(Rmutex<=0)//表示如果Rmutex<=0,则从等待队列中选择读者进入Rcount的临界区 { intk,j; j=r_wait[0]; for(k=0;k r_wait[k]=r_wait[k+1]; radd(j); } read(i); } //进行读操作 voidread(inti) { r[i]=1; } //模拟读之后对Rmutex的P操作,读操作完成的时候调用 voidrsub_p(inti) { r[i]=0; Rmutex--; rsub(i); } //对Rcount减1的控制 voidrsub(inti) { Rcount--; if(Rcount==0) read_v(i); else rsub_v(i); } //模拟读者对Wmutex的V操作 voidread_v(inti){ Wmutex++; if(Wmutex<=0)//表示如果Wmutex<=0,则从等待队列中选择写者或读者进行操作 { intk,j; if((w_wait[0]>=0)&&(w_wait[0] { j=w_wait[0]; for(k=0;k w_wait[k]=w_wait[k+1]; write(j); } else { j=r_wait[0]; for(k=0;k w_wait[k]=w_wait[k+1]; for(k=0;k r_wait[k]=r_wait[k+1]; radd_v(j); } } rsub_v(i); } //模拟读之后对Rmutex的V操作 voidrsub_v(inti) { Rmutex++; } intmain() { cout<<"\t\t\t==========读者--写者问题演示=========="< cout< cout<<"请输入写者个数(1-10): "; cin>>w_num; while(w_num<1||w_num>10) { cout<<"输入有误,请重新输入写者个数(1-10): "; cin>>w_num; }//完成对写者个数的输入 cout<<"请输入读者个数(1-10): "; cin>>r_num; while(r_num<1||r_num>10) { cout<<"输入有误,请重新输入读者个数(1-10): "; cin>>r_num; }//完成对读者个数的输入 intx,k,j,a[20]; while (1) { cout<<"***********************************************************"< for(k=0;k<20;k++) a[k]=0; cout<<"Wmutex="< cout< for(k=0;k { if(w[k]==1) cout<<"==========写者"<<(k+1)<<"正在写=========="< } for(k=0;k { if(r[k]==1) cout<<"==========读者"<<(k+1)<<"正在读=========="< } if(w_wait[0]==-1){ cout<<"等待队列中无对象········"< cout< } else { cout<<"等待队列中有: "; for(k=0;k { if(w_wait[k]==10) for(j=0;j<5;j++) { if(r_wait[j]! =-1) cout<<"-->"<<"读者"<<(r_wait[j]+1)<<"\t"; } if((w_wait[k]>=0)&&(w_wait[k] cout<<"-->"<<"写者"<<(w_wait[k]+1)<<"\t"; } cout< } for(k=0;k { x=0; for(j=0;j { if(k==w_wait[j]) { a[k]=1; x=1; } } if(x==1) continue; cout<<"("<<(k+1)<<")写者"<<(k+1); if(w[k]==0) cout<<"申请"; else cout<<"完成"; } for(k=0;k { x=0; for(j=0;j { if(k==r_wait[j]) { a[k+w_num]=1; x=1; } } if(x==1) continue; cout<<"("<<(k+1+w_num)<<")读者"<<(k+1); if(r[k]==0) cout<<"申请"; else cout<<"完成"; } cout<<"("<<(w_num+r_num+1)<<")结束"< cout<<"请输入选项序号: "; cin>>x; while(x<1||x>(w_num+r_num+1)||a[x-1]==1) { if(a[x-1]==1) cout<<"该对象已在等待队列中,请重新输入: "; else cout<<"输入有误,请重新输入: "; cin>>x; } for(k=0;k { if(x==(k+1)) { if(w[k]==0) write_p(k); else write_v(k); break; } } for(k=0;k { if(x==(k+1+w_num)) { if(r[k]==0) radd_p(k); else rsub_p(k); break; } } if(x==(w_num+r_num+1)) return0; } } 5测试用例,运行结果与运行情况分析 5.1测试用例 本程序模拟读者和写者问题,每个读者和写者对读操作或写操作的申请和完成都由用户手动选择。 测试用例如下: 输入写者个数: 3 输入读者个数: 5 3、写者1申请写操作(选择选项 (1)) 4、写者3申请写操作(选择选项(3)) 5、读者2申请读操作(选择选项(5)) 6、写者1完成写操作(选择选项 (1)) 7、读者5申请读操作(选择选项(8)) 8、写者3完成写操作(选择选项(3)) 9、读者5完成读操作(选择选项(8)) 10、读者2完成读操作(选择选项(5)) 11、结束(选择选项(9)) 5.2运行结果 结果一: 结果二: 结果三: 5.3运行结果分析 1、输入写者个数: 3 2、输入读者个数: 5 3、刚开始时Wmutex=1Rcount=0Rmutex=1,写者1申请写操作,此时,信号量Wmutex减1,所以Wmutex=0,写者1可以直接开始写操作 4、写者3申请写操作 此时,信号量Wmutex减1,所以Wmutex=-1,写者1正在写,所以写者3进入等待队列 5、读者2申请读操作 此时,信号量Rmutex减1,所以Rmutex=0,Rcount加1,所以Rcount=1,又因为Rcount=1,所以Wmutex减1,Wmutex=-2,写者1正在写,所以读者2进入等待队列 6、写者1完成写操作 此时,信号量Wmutex加1,所以Wmutex=-1,写者3开始写操作 7、读者5申请读操作 此时,信号量Rmutex减1,所以Rmutex=-1,读者2还在Rcount的临界区中,所以读者5等待 8、写者3完成写操作 此时,信号量Wmutex加1,所以Wmutex=0,读者2从等待队列中取出,并且Rmutex加1,则Rmutex=0,读者2开始读操作,读者5进入Rcount的临界区,Rcount加1,Rcount=2,Rmutex加1,Rmutex=1,此时读者5可直接开始读操作,所以此时,读者2和读者5正在进行读操作 9、读者5完成读操作 此时Rcount减1,Rcount=1,还剩读者2在进行读操作 10、读者2完成读操作 此时Rcount减1,Rcount=0,Wmutex加1,所以Wmutex=1 11、结束 6总结与心得 本课程设计是学生学习完《计算机操作系统》课程后,进行的一次全面的综合训练,通过课程设计,我更好地掌握了操作系统的原理及实现方法,加深对操作系统基础理论和重要算法的理解,加强了动手能力。 在设计过程中,出现了很多问题,比如对涉及到的知识没有深入的理解,对其实现方法感到很模糊,有时不知道该用什么方案来解决该问题,但通过自己查资料,进行深入的了解后,渐渐对其所用到的知识和方法有了清晰的认识、理解,能根据问题描述逐步对问题进行分析、抽象,并将其进行转化,最后通过编程实现该问题所描述的功能。 这次自己的收获还是不小,首先使我提高了分析问题,并根据需求转化成相应的程序结构的能力;其次也丰富了自己编写程序,调试程序的经验,这使得我编程时可能出现的错误的认识,并如何去避免产生了新的认识。 总的来说,通过本次设计收获很大。 首先更加熟练的掌握了通过P、V原语和信号量解决一些问题的思想。 其次,编程能力得到提高。 在开始编程的时候发现程序并不像想象中的那样容易实现,最后终于通过把写者和读者进程分别分割为若干个函数,并通过其中的相互衔接实现了模拟。 同时运行时对操作界面中的选项动态的给出很重要,例如,若某个写者还没有申请写操作,则给出的该选项为写者i申请;若某个写者在等待队列中,则不给出该写者的选项;若某个写者正在进行写操作,则给出的该选项为写者i完成。 读者和写者问题,一直认为这些东西很简单,但是具体编程实现其模拟并不容易。 虽然这还不算真正的实践,但通过这次设计,向实践靠近了一步。 更加深刻的理解了操作系统中这些理论知识的意义。 路漫漫其修远兮,吾将上下而求索!
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- OS 课程设计 读者