生產者 消費者模型

2021-07-30 05:45:35 字數 2678 閱讀 4938

在寫生產者—消費者模型時,先談及乙個概念——訊號量。

sem函式:

(1)sem_init函式是posix訊號量操作中的函式。

sem_init() 初始化乙個定位在 sem 的匿名信號量。

value 引數指定訊號量的初始值。 pshared 引數指明訊號量是由程序內線程共享,還是由程序之間共享。如果 pshared 的值為 0,那麼訊號量將被程序內的執行緒共享,並且應該放置在這個程序的所有執行緒都可見的位址上(如全域性變數,或者堆上動態分配的變數)。

函式原型:int sem_init(sem_t *sem, int pshared, unsigned int value);

如果 pshared 是非零值,那麼訊號量將在程序之間共享,並且應該定位共享記憶體區域(見 shm_open(3)、mmap(2) 和 shmget(2))。因為通過 fork(2) 建立的孩子繼承其父親的記憶體對映,因此它也可以見到這個訊號量。所有可以訪問共享記憶體區域的程序都可以用 sem_post(3)、sem_wait(3) 等等操作訊號量。初始化乙個已經初始的訊號量其結果未定義。

(2)sem_wait函式也是乙個原子操作,它的作用是從訊號量的值減去乙個「1」,但它永遠會先等待該訊號量為乙個非零值才開始做減法。//p操作

也就是說,如果你對乙個值為2的訊號量呼叫sem_wait(),執行緒將會繼續執行,將訊號量的值將減到1。如果對乙個值為0的訊號量呼叫sem_wait(),這個函式就會原地等待直到有其它執行緒增加了這個值使它不再是0為止。如果有兩個執行緒都在sem_wait()中等待同乙個訊號量變成非零值,那麼當它被第三個執行緒增加 乙個「1」時,等待執行緒中只有乙個能夠對訊號量做減法並繼續執行,另乙個還將處於等待狀態。sem_trywait(sem_t *sem)是函式sem_wait的非阻塞版,它直接將訊號量sem減1,同時返回錯誤**。

函式原型 :int sem_wait(sem_t * sem);

sem_wait() 減小(鎖定)由sem指定的訊號量的值.如果訊號量的值比0大,那麼進行減一的操作,函式立即返回.

如果訊號量當前為0值,那麼呼叫就會一直阻塞直到或者是訊號量變得可以進行減一的操作

(例如,訊號量的值比0大),或者是訊號處理程式中斷呼叫

sem_trywait() 和 sem_wait()是一樣的,除了如果不能夠對訊號量立即進行減一,

那麼sem_trywait()就會返回乙個錯誤(錯誤號是again)而不是鎖定. //非阻塞式等待

sem_timedwait() 和 sem_wait()是一樣的,除了如果減一操作不能立即執行的話,

(3)sem_destroy() 銷毀由sem指向的匿名信號量。

函式原型:int sem_destroy(sem_t *sem);

sem_destroy() 銷毀由sem指向的匿名信號量。

只有通過sem_init(3) 初始化的訊號量才應該使用sem_destroy() 銷毀。

銷毀乙個有其它執行緒或程序當前阻塞(在sem_wait(3))的訊號量將導致未定義行為。

使用乙個已經銷毀的訊號量將導致未定義結果,除非這個訊號量已經使用sem_init(3) 重新初始化了。

返回值:sem_destroy() 成功時返回 0;錯誤時,返回 -1,並把errno設定為合適的值。

(4)sem_post是給訊號量的值加上乙個「1」,它是乙個「原子操作」---即同時對同乙個訊號量做加「1」操作的兩個執行緒是不會衝突的;而同 時對同乙個檔案進行讀、加和寫操作的兩個程式就有可能會引起衝突。//v操作

函式原型:int sem_post(sem_t *sem);

訊號量的值永遠會正確地加乙個「2」--因為有兩個執行緒試圖改變它。 當有執行緒阻塞在這個訊號量上時,呼叫這個函式會使其中乙個執行緒不在阻塞,選擇機制是有執行緒的排程策略決定的。

返回值:sem_post() 成功時返回 0;錯誤時,訊號量的值沒有更改,-1 被返回,並設定 errno 來指明錯誤。

生產者-消費者模型(環形佇列實現)

(1)用計數器實現判空,判滿

(2)在隊列為空時,保證生產者先進行,隊列為滿時,消費者先進行

**如下:

源**如下:

#include

#include

#include

#include

#include

#define size 64 //環形佇列大小64

sem_t blanks; //格仔

sem_t datas; //資料

int ring[size];

void* producer(void* arg)

sleep(1);

}void* consumer(void* arg)

}int main()

執行結果如下:

生產者消費者模型

1.生產者消費者問題 producer consumer 有限緩衝,多執行緒同步。生產者執行緒和消費者執行緒共享固定大小緩衝區。2.關鍵是保證生產者不會再緩衝區滿時加入資料,消費者不會在緩衝區空時消耗資料。3.解決辦法 讓生產者在緩衝區滿時休眠,等下次消費者消耗緩衝區中的資料的時候,生產者才能被喚醒...

生產者消費者模型

生產者與消費者 3,2,1 三種關係 生產者與消費者 互斥,同步 消費者與消費者 互斥 生產者與生產者 互斥 條件變數 int pthread cond destroy pthread cond t cond int pthread cond init pthread cond t restrict...

生產者消費者模型

當佇列滿時,生產者需要等待佇列有空間才能繼續往裡面放入商品,而在等待的期間內,生產者必須釋放對臨界資源 即佇列 的占用權。因為生產者如果不釋放對臨界資源的占用權,那麼消費者就無法消費佇列中的商品,就不會讓佇列有空間,那麼生產者就會一直無限等待下去。因此,一般情況下,當佇列滿時,會讓生產者交出對臨界資...