文章目錄
- 介紹
- 一、什么是進(jìn)程同步,進(jìn)程互斥
-
二、讀者-寫者問題概述
- 1.概念圖
- 2.實例代碼
- 總結(jié)
介紹
通過實驗?zāi)M讀者和寫者之間的關(guān)系,了解并掌握他們之間的關(guān)系及其原理。由此增加對進(jìn)程同步的問題的了解。具體如下:
? 1)掌握基本的同步互斥算法,理解讀者和寫者模型;
? 2)了解windows中多線程(多進(jìn)程)的并發(fā)執(zhí)行機(jī)制,線程(進(jìn)程)間的同步和互斥;
? 3)學(xué)習(xí)使用windows中基本的同步對象,掌握相應(yīng)的API。
提示:以下是本篇文章正文內(nèi)容,下面案例可供參考
一、什么是進(jìn)程同步,進(jìn)程互斥
進(jìn)程同步:對多個并發(fā)的進(jìn)程在執(zhí)行次序上進(jìn)行協(xié)調(diào),使其能按照一定的規(guī)則共享資源系統(tǒng),使程序的執(zhí)行有可在現(xiàn)性
進(jìn)程互斥:間接相互制約關(guān)系,由于共享資源的征用問題,系統(tǒng)實施統(tǒng)一的分配,使并發(fā)的程序之間有相互制約關(guān)系
二、讀者-寫者問題概述
1.概念圖
? ? ? 調(diào)試一個采用“讀寫平等”策略的“讀者-寫者”問題的模擬程序。
利用模擬用信號量機(jī)制實現(xiàn)讀者和寫者問題:通過用戶控制讀進(jìn)程和寫進(jìn)程,反應(yīng)讀者和寫者問題中所涉及的進(jìn)程的同步與互斥
?問題描述:
? ? ? 模擬用信號量機(jī)制實現(xiàn)讀者和寫者問題,即有兩組并發(fā)進(jìn)程:讀者和寫者,共享一組數(shù)據(jù)區(qū),進(jìn)行讀寫操作,要求任一時刻“寫者”最多只允許一個,而“讀者”則允許多個。
?規(guī)則說明:
允許多個讀者同時執(zhí)行讀操作;
不允許讀者、寫者同時操作;
不允許多個寫者同時操作。
問題分析:
互斥關(guān)系:寫進(jìn)程-寫進(jìn)程,讀進(jìn)程-寫進(jìn)程
設(shè)置一個p(rw),V(rw),實現(xiàn)對共享文件的枷鎖和解鎖,讀進(jìn)程和讀進(jìn)程之間要同時訪問,寫進(jìn)程和讀進(jìn)程之間要互斥訪問,可以讓第一個讀進(jìn)程枷鎖,最后一個讀進(jìn)程解鎖,設(shè)置一個變量count來記錄有幾個讀進(jìn)程在訪問。
寫者進(jìn)程:
讀者進(jìn)程
?文章來源:http://www.zghlxwxcb.cn/news/detail-787725.html
?
2.實例代碼
#include<iostream>
#include<string>
using namespace std;
int r_num;//讀者個數(shù)
int w_num;//寫者個數(shù)
int Wmutex=1;//表示允許寫或允許讀
int Rcount=0;//表示正在讀的進(jìn)程數(shù)
int Rmutex=1;//表示對Rcount的互斥操作
int r[10]={0,0,0,0,0,0,0,0,0,0};//表示讀者的狀態(tài),1表示正在讀
int w[10]={0,0,0,0,0,0,0,0,0,0};//表示寫者的狀態(tài),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表示對應(yīng)的讀者,-1為空
void write_p(int i);//模擬寫者對Wmutex的P操作,同時也作為寫者進(jìn)程的入口
void write(int i);//開始寫操作
void write_v(int i);//模擬寫者對Wmutex的V操作,寫操作完成的時候調(diào)用
void radd_p(int i);//模擬讀之前對Rmutex的P操作,同時也作為讀者進(jìn)程的入口
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操作,讀操作完成的時候調(diào)用
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,則該寫者進(jìn)入等待隊列
{
w_wait[-Wmutex-1]=i;
}
else
write(i);
}
void write_v(int i)
{
w[i]=0;
Wmutex++;
if(Wmutex<=0) //表示如果Wmutex<=0,則從等待隊列中選擇寫者或讀者進(jìn)行操作
{
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,則進(jìn)入等待隊列
{
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,則進(jìn)入等待隊列
{
w_wait[-Wmutex-1]=10;
r_wait[0]=i;
}
else
radd_v(i);
}
void radd_v(int i)
{
Rmutex++;
if(Rmutex<=0) //表示如果Rmutex<=0,則從等待隊列中選擇讀者進(jìn)入Rcount的臨界區(qū)
{
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,則從等待隊列中選擇寫者或讀者進(jìn)行操作
{
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<<"請輸入寫者個數(shù)(1到10):";
cin>>w_num;
while(w_num<1||w_num>10)
{
cout<<"輸入有誤,請重新輸入寫者個數(shù)(1到10):";
cin>>w_num;
}//完成對寫者個數(shù)的輸入
cout<<"請輸入讀者個數(shù)(1到10):";
cin>>r_num;
while(r_num<1||r_num>10)
{
cout<<"輸入有誤,請重新輸入讀者個數(shù)(1到10):";
cin>>r_num;
}//完成對讀者個數(shù)的輸入
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)<<")結(jié)束"<<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;
}
}
總結(jié)
喜歡的話,點(diǎn)個關(guān)注吧文章來源地址http://www.zghlxwxcb.cn/news/detail-787725.html
到了這里,關(guān)于用信號量機(jī)制解決讀者-寫者問題C語言實現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!