OS实验指导进程同步模拟分解.docx
《OS实验指导进程同步模拟分解.docx》由会员分享,可在线阅读,更多相关《OS实验指导进程同步模拟分解.docx(15页珍藏版)》请在冰点文库上搜索。
OS实验指导进程同步模拟分解
《操作系统》实验指导一
开课实验室:
A2092015-9-14
实验项目
(一)进程同步模拟实验
实验类型
验证
实验学时
2
一、实验目的
通过实验模拟读者和写者之间的关系,了解并掌握他们之间的关系及其原理。
由此增加对进程同步的问题的了解。
具体如下:
1)掌握基本的同步互斥算法,理解读者和写者模型;
2)了解windows中多线程(多进程)的并发执行机制,线程(进程)间的同步和互斥;
3)学习使用windows中基本的同步对象,掌握相应的API。
二、设备与环境
1.硬件设备:
PC机一台
2.软件环境:
安装Windows操作系统或者Linux操作系统,并安装相关的程序开发环境,如C\C++\Java等编程语言环境。
三、实验要求
用高级语言编写和调试一个采用“读写平等”策略的“读者-写者”问题的模拟程序。
利用模拟用信号量机制实现读者和写者问题:
通过用户控制读进程和写进程,反应读者和写者问题中所涉及的进程的同步与互斥。
1.问题描述:
模拟用信号量机制实现读者和写者问题,即有两组并发进程:
读者和写者,共享一组数据区,进行读写操作,要求任一时刻“写者”最多只允许一个,而“读者”则允许多个。
2.规则说明:
允许多个读者同时执行读操作;
不允许读者、写者同时操作;
不允许多个写者同时操作。
四、实验设计参考
1.分析读者和写者的相互关系:
1)“读-写”互斥,即不能同时有一个读者在读,同时去有一个写者在写;
2)“写-写”互斥,即不能有两个写者同时进行写操作;
3)“读-读”允许,即可以有两个以上的读者同时进行读操作。
2.采用的信号量机制
1)Wmutex表示读写的互斥信号量,初值:
Wmutex=1;
2)公共变量Rcount表示“正在读”的进程数,初值:
Rcount=0;
3)Rmutex:
表示对Rcount的互斥操作,初值:
Rmutex=1。
main()
{intWmutex=1;
intRmutex=1;
intRcount=0;
cobegin
read1();
…
readi();
write1();
…
writej();
coend}
读者进程:
Readn()
{P(Rmutex);
Rcount++;
if(Rcount==1)
P(Wmutex);
V(Rmutex);
读
P(Rmutex);
Rcount--;
if(Rcount==0)V(Wmutex);
V(Rmutex);
while(false);
写者进程:
writem()
{
P(Wmutex);
写
V(Wmutex);
}
设计中首先用户输入读者个数r_num和写者个数w_num,来模拟用信号量机制实现r_num个读者和w_num个写者同时处理一个数据区的问题。
所有的读者或写者对操作的申请和完成都是由用户控制,更容易反映读者和写者问题的规律。
3.算法流程图
4.数据结构说明
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为空
5.模块说明
四组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操作
源程序的主要部分
1写操作的设计:
模拟写者对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;kwrite(j);
}
else
{
j=r_wait[0];
for(k=0;kfor(k=0;kradd_v(j);
}
}
}
2.读操作的设计:
模拟读之前对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;kradd(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;kwrite(j);
}
else
{
j=r_wait[0];
for(k=0;kfor(k=0;kradd_v(j);
}
}
rsub_v(i);
}
模拟读之后对Rmutex的V操作:
voidrsub_v(inti)
{
Rmutex++;
}
3主函数的设计:
intmain()
{
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="<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<<"等待队列中无对象"<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);
}
if((w_wait[k]>=0)&&(w_wait[k]cout<<"-->"<<"写者"<<(w_wait[k]+1);
}
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<<"申请";
elsecout<<"完成";
}
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<<"申请";
elsecout<<"完成";
}
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<<"该对象已在等待队列中,请重新输入:
";
elsecout<<"输入有误,请重新输入:
";
cin>>x;
}
for(k=0;k{
if(x==(k+1))
{
if(w[k]==0)write_p(k);
elsewrite_v(k);
break;
}
}
for(k=0;k{
if(x==(k+1+w_num))
{
if(r[k]==0)radd_p(k);
elsersub_p(k);
break;
}
}
if(x==(w_num+r_num+1))return0;
}
}
五、测试用例,运行结果与运行情况分析
1.测试用例
本程序模拟读者和写者问题,每个读者和写者对读操作或写操作的申请和完成都由用户手动选择。
测试用例如下:
1、输入写者个数:
3
2、输入读者个数:
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))
2.结果分析
(此项需有运行结果的抓图,并附分析,其中分析的形式如下,例如:
1、输入写者个数:
3
2、输入读者个数:
5
3、刚开始时Wmutex=1Rcount=0Rmutex=1
写者1申请写操作
此时,信号量Wmutex减1,所以Wmutex=0
写者1可以直接开始写操作……)
六、自我评价与总结:
可从以下几方面阐述:
)你认为你完成的设计哪些地方做得比较好或比较出色;
)什么地方做得不太好,以后如何改正;
)从本设计得到的收获(在编写,调试,执行过程中的经验和教训);
)完成本题是否有其他的其他方法(如果有,简要说明该方法);