生產者和消費者問題是執行緒模型中的經典問題:生產者和消費者在同一時間段內共用同乙個儲存空間,生產者往儲存空間中新增產品,消費者從儲存空間中取走產品,當儲存空間為空時,消費者阻塞,當儲存空間滿時,生產者阻塞。
為什麼要使用生產者和消費者模式:
生產者——消費者模型中,生產者和消費者執行緒之間需要傳遞一定量的資料,兩個執行緒會使用乙個特定大小的共享環形緩衝器。
生產者向緩衝器中寫入資料,直到它到達緩衝器的終點;然後它會再次從起點重新開始,覆蓋已經存在的資料。消費者執行緒則會讀取生成的資料。
在生產者——消費者例項中,對於同步的需求有兩個部分:
1.如果生產者執行緒生成資料的速度太快,那麼將會把消費者執行緒還沒有讀取的資料覆蓋;
2.如果消費者執行緒讀取資料的速度過快,那麼它就會越過生產者執行緒而讀取一些垃圾資料。
讓生產者執行緒填滿緩衝器,然後等待消費者執行緒讀取完緩衝器中全部資料。
使用兩個訊號量:freespace 與 usedspace
freespace 訊號量控制生產者執行緒寫入資料的那部分緩衝器, usedspace 訊號量則控制消費者執行緒讀取資料的那部分緩衝器區域。
這兩個區域是相互補充的。
常用緩衝區容量值初始化 freespace 訊號量,意味著它最多可以獲取的緩衝器資源量。
在啟動這個應用程式時,消費者執行緒就會獲得自由的位元組並把它們轉換為用過的位元組。
用0初始化usedspace訊號量,以確保消費者執行緒不會在一開始就讀取到垃圾資料。
在生產者執行緒中,每次反覆寫入都是從獲取乙個 freespace 開始。
如果該緩衝器中充滿了消費者執行緒還沒有讀取的資料,那麼對acquire()的呼叫就會被阻塞,直到消費者執行緒開始消費這些資料。
一旦生產者執行緒獲取這一位元組,就寫入資料,並將這個位元組釋放為 usedspace ,以讓消費者執行緒讀取到。
在消費者執行緒中,我們從獲取乙個 usedspace 開始。
如果緩衝器中還沒有任何可用的資料,那麼將會阻塞對acquire()呼叫,直到生產者執行緒生產資料。
一旦獲取到這個位元組,就使用資料,並把位元組釋放為 freespace ,這樣,生產者執行緒就可以再次寫入。
上述方法在只有乙個生產者和乙個消費者時能解決問題。對於多個生產者或者多個消費者共享緩衝區的情況,該演算法也會導致競爭條件,出現兩個或以上的程序同時讀或寫同乙個緩衝區槽的情況。
為了保證同一時刻只有乙個生產者能夠執行 putitemintobuffer()。也就是說,需要尋找一種方法來互斥地執行臨界區的**。為了達到這個目的,可引入乙個二值訊號燈 mutex,其值只能為 1 或者 0。如果把執行緒放入 down(mutex) 和 up(mutex) 之間,就可以限制只有乙個執行緒能被執行。
static unsigned char g_buff[size] = ;
static qsemaphore g_sem_free(size);
static qsemaphore g_sem_used(0);
static qsemaphore mutex(1);
class producer : public qthread
std::cerr<<"p";
++usedspace;
bufferisnotempty.wakeall();
mutex.unlock();}}
};class consumer : public qthread
std::cerr<<"c";
--usedspace;
bufferisnotfull.wakeall();
mutex.unlock();
}std::cerr<
OS 程序同步 生產者消費者
注意 在每個程式中多個wait操作順序不可以顛倒。應先執行對資源訊號量的wait操作,然後再執行對互斥訊號量的wait操作,否則可能引起程序死鎖。概述 p操作 同步再前,互斥再後 記錄型訊號量 include using namespace std int in 0 佇列的隊首 int out 0 ...
C 模擬「生產者消費者」程序同步問題
include include include include include using namespace std const int limit 30 生產總量 const int maxsize 10 緩衝區大小 const int kind 7 int bufidx 0 當前緩衝區下標 s...
Linux下程序同步問題 生產者消費者
設計思路,首先有緩衝區內資源,生產者消費者都用,而且是資源訊號量,那麼需要建立兩個訊號量,乙個代表空閒的個數,乙個代表非空閒個數。同時緩衝區的使用是互斥的,所以需要建立乙個互斥訊號量。include include include include include include include in...