生產者消費者問題之互斥量和訊號量實現

2021-08-19 19:14:27 字數 1803 閱讀 5422

可以使用pthread的互斥介面來保護資料,確保同一時間只有乙個執行緒訪問資料。互斥量從本質上說是一把鎖,在訪問共享資源前對互斥量進行設定(加鎖),在訪問完成後釋放(解鎖)互斥量。對互斥量進行加鎖以後,任何其他試圖再次對互斥量進行加鎖的執行緒都會被阻塞直到當前執行緒釋放該互斥鎖。如果釋放乙個互斥量時有乙個以上的執行緒阻塞,那麼所有該鎖上的阻塞執行緒都被變成可執行狀態,第乙個變為執行的執行緒就可以對互斥量進行加鎖,其它執行緒執行緒就會看到互斥量依然是鎖著的,只能回去再次等待它重新變為可用。在這種方式下,每次只用乙個執行緒可以向前執行。

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

int sem_wait(sem_t *sem);

int sem_post(sem_t *sem);

sem_destroy(sem_t *sem);

sem_init用於對指定訊號初始化,pshared為0,表示訊號在當前程序的多個執行緒之間共享,value表示初始化訊號的值。

sem_wait可以用來阻塞當前執行緒,直到訊號量的值大於0,解除阻塞。解除阻塞後,sem的值-1,表示公共資源被執行減少了。

sem_post用於增加訊號量的值+1,當有執行緒阻塞在這個訊號量上時,呼叫這個函式會使其中的乙個執行緒不在阻塞,選擇機制由執行緒的排程策略決定。 

sem_destroy用於銷毀指定訊號量。

注:參考unix環境高階程式設計(第三版)

實現**:

#include #include #include #include #include #include #include #include #define err_exit(m)			\

do \

while(0); \

#define consumers_count 1 //消費者

#define producers_count 1 //生產者

#define buffsize 10 //緩衝區大小

int g_buffsize[buffsize]; //緩衝區

unsigned short in = 0; //存放的位置

unsigned short out = 0; //消費的位置

unsigned short produce_id = 0;         //當前正在生產的id

unsigned short consume_id = 0;         //當前正在消費的id

sem_t g_sem_full; //滿訊號量

sem_t g_sem_empty; //空訊號量

pthread_mutex_t g_mutex; //互斥鎖

pthread_t g_thread[consumers_count+producers_count];//執行緒id

void* consume(void *arg)

{ int i;

int num = (int)arg;

while (1)

{ //列印等待執行緒

printf(" %d consume wait \n",num);

sem_wait(&g_sem_empty); //等待空的訊號量,如果不空則消費產品

pthread_mutex_lock(&g_mutex);

//列印倉庫當前的狀態

for (i=0; i執行截圖:

互斥量,生產者消費者

如果不需要訊號量的計數能力,有時可以使用訊號量的乙個簡化版本,稱為互斥量 mutex 互斥量僅僅適用於管理共享資源或一小段 由於互斥量在實現時既容易又有效,這使得互斥量在實現使用者空間執行緒包時非常有用。互斥量是乙個可以處於兩態之一的變數 解鎖和加鎖。這樣,只需要乙個二進位制位表示它,不過實際上,常...

生產者 消費者模型之訊號量

訊號量 1 定義訊號量 sem t semaphore 定義乙個名為semaphore的訊號量 2 初始化訊號量 int sem init sem t sem,int pshared,unsigned int value 引數 sem t sem 要初始化的訊號量 int pshared pshar...

訊號量(生產者和消費者模型)

訊號量和管程都是作業系統用於同步提供的兩種方法,我們將結合生產者與消費者模型對此進行學習。為了提高系統的併發性,我們引入了多程序,多執行緒,但是這樣子帶來了資源競爭,也就是多個程式同時訪問乙個共享資源而引發的一系列問題,因此我們需要協調多執行緒對與共享資源的訪問,在任意時刻保證只能有乙個執行緒執行臨...