消費者模型
生産者-消費者問題是一個經典的程序同步問題,生産者程序在生産産品,并将這些産品提供給消費者程序去消費。為使生産者程序與消費者程序能并發執行,在兩者之間設定一個具有N個緩沖區的緩沖池,生産者程序将它所生産的産品放入一個緩沖區;消費者程序可從一個緩沖區中取走産品去消費。當緩沖區滿的時候生産者就不能放,當緩沖區空的時候消費者就不能取。
以下是我在Linux下實作的生産者消費者模型:
讀者寫者模型
讀者與寫者問題的特點在于讀者不使緩沖區數量改變,并且多個讀者可以同時讀取緩沖區資訊,而寫者與寫者、寫者與讀者隻能互斥通路緩沖區的相同資料。對于相同的資料項,多個讀者之間可以同時通路;對于相同的資料項,多個寫者或寫者與讀者之間不能同時通路。
兩個模型之間的差別
從兩個模型的原理中可以看出,兩個模型最大的差別在于在生産者消費者模型中,生産者與生産者是互斥關系,消費者和消費者是互斥關系,生産者和消費者之間是互斥與同步關系;而在讀者寫者模型中,讀者和讀者沒有關系,寫者和寫者是互斥關系,讀者和寫者是互斥與同步關系。
對讀者和寫者模型的深入探究
實作此模型的操作:
int count_Reader=; //記錄正在讀的讀者數
int mutex_Count_Reader=; //用于讀者之間互斥通路count_Reader
int mutex_Reader_Writer=; //用于讀者與寫者之間的互斥和寫者與寫者之間的互斥
Reader
{
while(ture)
{
p( mutex_Count_Reader );
if( == count_Reader ) //如果目前的讀者數為0,就要先去檢查一下是不是寫者正在寫
p( mutex_Reader_Writer); //如果寫者正在寫,讀者就會阻塞在此處
++ count_Reader;
v( mutex_Count_Reader);
進行讀操作;
p( mutex_Count_Reader );
- - count_Reader;
if( == count_Reader ) //如果讀者數已經為0,說明所有讀者都讀完了,寫者可以寫啦
v( mutex_Reader_Writer);
v( mutex_Count_Reader );
}
}
Writer
{
while(true)
{
p( mutex_Reader_Writer);
進行寫操作
v( mutex_Reader_Writer);
}
}
這其實是一個讀者優先的算法。
設想一下,如果此時有多個讀者和寫者都在等待,而此時又是讀者正在讀,讀者就一直占着mutex_Reader_Writer信号量,等待的讀者可以進去讀,但寫者就要等所有的讀者讀完後才能寫,這就會造成寫者饑餓的問題。解決方法是設定寫者優先。
寫者優先
寫者優先算法要解決的是在上面的基礎上,當讀者和寫者同時等待時,讓寫者先進去寫。
int count_Reader=; //記錄正在讀的讀者數
int count_Writer=; //記錄正在等待的寫者數
int mutex_Count_Reader=; //讀者之間互斥通路count_Reader
int mutex_Count_Writer=; //寫者之間互斥通路count_Writer
int mutex_Reader_Writer=; //讀者與寫者之間的互斥
int mutex_write=; //寫者與寫者之間的互斥
Reader
{
P( mutex_Count_Writer ); //如果有寫者在等待,就阻塞讀者程序,這樣就能保證寫者優先
V( mutex_Count_Writer );
P( count_Reader );
if( == count_Reader )
p( mutex_Reader_Writer); //如果寫者正在寫,讀者就會阻塞在此處
++ count_Reader;
V( mutex_Count_Reader);
進行讀操作;
P( mutex_Count_Reader );
- - count_Reader;
if( == count_Reader )
v( mutex_Reader_Writer);
V( mutex_Count_Reader );
}
Writer
{
P( mutex_Count_Writer );
if( == count_Writer )
p( mutex_Reader_Writer);
++count_Writer;
V( mutex_Count_Writer);
寫操作;
P( mutex_Count_Writer );
- -count_Writer;
if( == count_Writer )
V( mutex_Reader_Writer);
V( mutex_Count_Writer );
}