Linux 基於環形佇列的生產消費模型

2021-09-25 20:48:00 字數 2338 閱讀 3813

在上篇部落格基於阻塞佇列的生產者消費者模型中我介紹了什麼是生產者消費者模型,還沒了解的可以戳鏈結檢視。本篇部落格也是實現乙個生產者消費者模型,只是這篇部落格我將基於迴圈佇列實現生產消費模型。

posix 訊號量

這裡要注意了,我們這次使用的是基於posix的訊號量,千萬不要誤認為是systemv的訊號量,雖然兩個東西不一樣,但是他們的作用相同,他們都是用於保證同步的操作,達到無衝突訪問共享資源的目的,但是posix訊號量可以用於執行緒同步。

訊號量本質上是乙個記錄臨界資源數目的計數器,它有兩個很重要的操作,乙個是加操作,也被稱為v操作,此操作會讓訊號量加一,另乙個操作為減操作,也被稱為p操作,此操作會讓訊號量值減一,接下來我們看看訊號量的操作函式。

這裡需要特別注意一點:雖然它只是是乙個計數器,但是不能用全域性變數代替,因為訊號量的pv操作是具有原子性的,而我們自己定義的全域性變數無法保證原子性。

訊號量的相關操作

初始化訊號量

#include

int sem_init(sem_t *sem,int pshared,unsigned int value);

sem:訊號量

//pshared:0表示執行緒間共享,非零表示程序間共享

//value:訊號量初始值

摧毀訊號量

int sem_destroy(sem_t *sem);

等待訊號量

int sem_wait(sem_t *sem);

功能:等到訊號量時會將訊號量的值減一,對應p操作

發布訊號量

int sem_post(sem_t *sem);

功能:資源使用結束後,歸還資源將訊號量的值加一,對應v操作

基於迴圈佇列的生產消費模型

上節中,我們實現了基於阻塞佇列的,其空間大小可以進行動態分配。

現在我們將基於固定大小的環形佇列再次實現這個模型。生產者每向佇列中生產一批資料,消費者就可以從佇列中讀取到一批資料,所以此時迴圈佇列就變成了交易場所,p表示生產者,c表示消費者,當生產者向佇列中push後消費者就可以將資料拿走。

這裡有幾個原則需要遵循:

消費行為不能先於生產行為

生產行為不能超過消費行為一圈

雖然空 / 滿的狀態不好確定,但它倆一定是在同一點

隊列為空時只能有生產行為,為滿時只能有消費行為

這時最大的問題是:環形結構的其實狀態和結束狀態都是一樣的,不好判斷為空還是未滿,所以我們通過加計數器或者標誌位來判斷,也可以通過預留乙個空的位置作為滿的狀態。我們現在有訊號量這個計數器,所以我們用陣列moni 環形佇列,用模運算模擬環形的特性。就能很簡單的實現多執行緒間的同步過程。

生產者(p)的操作包括取空位增資料

p(sem_space)空位個數- -

v(sem_data)資料個數+ +

消費者(c)的操作包括取資料增空位

p ( sem_data ) 資料個數- -

v(sem_space) 空位個數+ +

話不多說,看下面的**就能明白啦:

#include  #include #include #include #include #include #include #define num 16

using namespace std;

class ringqueue

void putdata(const int &data) //生產者行為

void getdata(int &data) //消費者行為

~ringqueue()

};void *consume(void *arg)

{ ringqueue *rq=(ringqueue*)arg;

int data;

while(1)

{ rq->getdata(data);

cout<

cout<

相信這裡的**也很容易理解。

我們現在實現了基於阻塞佇列和基於訊號量的生產者消費者模型,對於他們的實現其實都不是很難,重點是讀者們需要理解問題解決的辦法和理解模型本身的作用和意義。

基於環形佇列的的生產者消費者模型

在linxu的多執行緒機制中,由於可能同時對臨界資源進行讀寫操作,因此互斥鎖經常被用來進行互斥操作。初次之外訊號量和環形佇列等互斥機制則使用起來更為簡單。include include include include define size 1024 環形佇列 int arr size sem t ...

基於環形佇列的生產者消費者模型編寫。

1.環形佇列 在隊列為空時,生產者必須先執行,消費者不能越過生產者 在隊列為滿時,消費者先執行,生產者不能超過消費者一圈,不能同時訪問同一位置 2.訊號量sem t sem posix的執行緒標準下的 訊號量機制通過訊號量的值控制可用資源的數量。執行緒訪問共享資源前,需要申請獲取乙個訊號量,如果訊號...

Linux 基於環形buf的多消費者多生產者問題

生產者消費者問題,是乙個多執行緒 同步問題的經典案例。該問題描述了兩個共享固定大小 緩衝區的 執行緒 即所謂的 生產者 和 消費者 在實際執行時會發生的問題。生產者的主要作用是生成一定量的資料放到緩衝區中,然後重複此過程。與此同時,消費者也在緩衝區消耗這些資料。該問題的關鍵就是要保證生產者不會在緩衝...