文章目录
- 介绍
- 一、什么是进程同步,进程互斥
-
二、读者-写者问题概述
- 1.概念图
- 2.实例代码
- 总结
介绍
通过实验模拟读者和写者之间的关系,了解并掌握他们之间的关系及其原理。由此增加对进程同步的问题的了解。具体如下:
1)掌握基本的同步互斥算法,理解读者和写者模型;
2)了解windows中多线程(多进程)的并发执行机制,线程(进程)间的同步和互斥;
3)学习使用windows中基本的同步对象,掌握相应的API。
提示:以下是本篇文章正文内容,下面案例可供参考
一、什么是进程同步,进程互斥
进程同步:对多个并发的进程在执行次序上进行协调,使其能按照一定的规则共享资源系统,使程序的执行有可在现性
进程互斥:间接相互制约关系,由于共享资源的征用问题,系统实施统一的分配,使并发的程序之间有相互制约关系
二、读者-写者问题概述
1.概念图
调试一个采用“读写平等”策略的“读者-写者”问题的模拟程序。
利用模拟用信号量机制实现读者和写者问题:通过用户控制读进程和写进程,反应读者和写者问题中所涉及的进程的同步与互斥
问题描述:
模拟用信号量机制实现读者和写者问题,即有两组并发进程:读者和写者,共享一组数据区,进行读写操作,要求任一时刻“写者”最多只允许一个,而“读者”则允许多个。
规则说明:
允许多个读者同时执行读操作;
不允许读者、写者同时操作;
不允许多个写者同时操作。
问题分析:
互斥关系:写进程-写进程,读进程-写进程
设置一个p(rw),V(rw),实现对共享文件的枷锁和解锁,读进程和读进程之间要同时访问,写进程和读进程之间要互斥访问,可以让第一个读进程枷锁,最后一个读进程解锁,设置一个变量count来记录有几个读进程在访问。
写者进程:
读者进程
文章来源:https://www.toymoban.com/news/detail-787725.html
2.实例代码
#include<iostream>
#include<string>
using namespace std;
int r_num;//读者个数
int w_num;//写者个数
int Wmutex=1;//表示允许写或允许读
int Rcount=0;//表示正在读的进程数
int Rmutex=1;//表示对Rcount的互斥操作
int r[10]={0,0,0,0,0,0,0,0,0,0};//表示读者的状态,1表示正在读
int w[10]={0,0,0,0,0,0,0,0,0,0};//表示写者的状态,1表示正在写
int w_wait[11]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};//表示等待队列,0-9表示写者,10时需引入读者的等待队列,-1表示空
int r_wait[11]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};//读者的等待队列,0-9表示对应的读者,-1为空
void write_p(int i);//模拟写者对Wmutex的P操作,同时也作为写者进程的入口
void write(int i);//开始写操作
void write_v(int i);//模拟写者对Wmutex的V操作,写操作完成的时候调用
void radd_p(int i);//模拟读之前对Rmutex的P操作,同时也作为读者进程的入口
void radd(int i);//Rcount加1
void read_p(int i);//模拟读者对Wmutex的P操作
void radd_v(int i);//模拟读之前对Rmutex的V操作
void read(int i);//读
void rsub_p(int i);//模拟读之后对Rmutex的P操作,读操作完成的时候调用
void rsub(int i);//Rcount减1
void read_v(int i);//模拟读者对Wmutex的V操作
void rsub_v(int i);//模拟读之后对Rmutex的V操作
void write(int i)
{
w[i]=1;
}
void write_p(int i)
{
Wmutex--;
if(Wmutex<0) //表示如果Wmutex<0,则该写者进入等待队列
{
w_wait[-Wmutex-1]=i;
}
else
write(i);
}
void write_v(int i)
{
w[i]=0;
Wmutex++;
if(Wmutex<=0) //表示如果Wmutex<=0,则从等待队列中选择写者或读者进行操作
{
int k,j;
if((w_wait[0]>=0)&&(w_wait[0]<w_num))
{
j=w_wait[0];
for(k=0;k<w_num;k++) w_wait[k]=w_wait[k+1];
write(j);
}
else
{
j=r_wait[0];
for(k=0;k<w_num;k++) w_wait[k]=w_wait[k+1];
for(k=0;k<r_num;k++) r_wait[k]=r_wait[k+1];
radd_v(j);
}
}
}
void radd_p(int i) {
Rmutex--;
if(Rmutex<0) //表示如果Rmutex<0,则进入等待队列
{
r_wait[-Rmutex]=i;
}
else
radd(i);
}
void radd(int i)
{
Rcount++;
if(Rcount==1)
read_p(i);
else
radd_v(i);
}
void read_p(int i)
{
Wmutex--;
if(Wmutex<0) //表示如果Wmutex<0,则进入等待队列
{
w_wait[-Wmutex-1]=10;
r_wait[0]=i;
}
else
radd_v(i);
}
void radd_v(int i)
{
Rmutex++;
if(Rmutex<=0) //表示如果Rmutex<=0,则从等待队列中选择读者进入Rcount的临界区
{
int k,j;
j=r_wait[0];
for(k=0;k<r_num;k++) r_wait[k]=r_wait[k+1];
radd(j);
}
read(i);
}
void read(int i)
{
r[i]=1;
}
void rsub_p(int i)
{
r[i]=0;
Rmutex--;
rsub(i);
}
void rsub(int i)
{
Rcount--;
if(Rcount==0)
read_v(i);
else
rsub_v(i);
}
void read_v(int i) {
Wmutex++;
if(Wmutex<=0) //表示如果Wmutex<=0,则从等待队列中选择写者或读者进行操作
{
int k,j;
if((w_wait[0]>=0)&&(w_wait[0]<w_num))
{
j=w_wait[0];
for(k=0;k<w_num;k++) w_wait[k]=w_wait[k+1];
write(j);
}
else
{
j=r_wait[0];
for(k=0;k<w_num;k++) w_wait[k]=w_wait[k+1];
for(k=0;k<r_num;k++) r_wait[k]=r_wait[k+1];
radd_v(j);
}
}
rsub_v(i);
}
void rsub_v(int i)
{
Rmutex++;
}
int main()
{
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;
}//完成对读者个数的输入
int x,k,j,a[20];
while(1)
{
cout<<"************************************"<<endl;
for(k=0;k<20;k++) a[k]=0;
cout<<"Wmutex="<<Wmutex<<"Rcount="<<Rcount<<" Rmutex="<<Rmutex<<endl;
for(k=0;k<w_num;k++)
{
if(w[k]==1)
cout<<"-------写者"<<(k+1)<<"正在写"<<endl;
}
for(k=0;k<r_num;k++)
{
if(r[k]==1)
cout<<"-------读者"<<(k+1)<<"正在读"<<endl;
}
if(w_wait[0]==-1) cout<<"等待队列中无对象"<<endl;
else
{
cout<<"等待队列中有:";
for(k=0;k<w_num;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]<w_num))
cout<<"-->"<<"写者"<<(w_wait[k]+1);
}
cout<<endl;
}
for(k=0;k<w_num;k++)
{
x=0;
for(j=0;j<w_num;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<r_num;k++)
{
x=0;
for(j=0;j<r_num;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)<<")结束"<<endl;
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<w_num;k++)
{
if(x==(k+1))
{
if(w[k]==0) write_p(k);
else write_v(k);
break;
}
}
for(k=0;k<r_num;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)) return 0;
}
}
总结
喜欢的话,点个关注吧文章来源地址https://www.toymoban.com/news/detail-787725.html
到了这里,关于用信号量机制解决读者-写者问题C语言实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!