C語言條件變數和訊號量兩種方式實現生產者消費者問題

2021-10-10 23:13:57 字數 3442 閱讀 8764

生產者拿到互斥鎖後,檢查緩衝區的產品數量:

如果緩衝區是滿的,則生產者條件等待

如果緩衝區不是滿的,就生產,然後傳送訊號喚醒消費者消費,釋放互斥鎖

消費者拿到互斥鎖後,檢查緩衝區的產品數量:

如果緩衝區是空的,則消費者條件等待

如果緩衝區不是空的,就消費,然後傳送訊號喚醒生產者生產,釋放互斥鎖

生產者拿到互斥鎖後,檢查緩衝區的產品數量:

如果緩衝區不是滿的,就生產,然後傳送訊號喚醒消費者消費,釋放互斥鎖

消費者拿到互斥鎖後,檢查緩衝區的產品數量:

如果緩衝區是空的,則消費者條件等待

如果緩衝區不是空的,就消費,釋放互斥鎖

生產者拿到互斥鎖後,檢查緩衝區的產品數量:

如果緩衝區是滿的,則生產者條件等待

如果緩衝區不是滿的,就生產,釋放互斥鎖

消費者拿到互斥鎖後,檢查緩衝區的產品數量:

如果緩衝區不是空的,就消費,然後傳送訊號喚醒生產者生產,釋放互斥鎖

第2,3兩種是子集,只需要去除對應**即可

#include

#include

#include

#include

// 生產者消費者的數量

#define consumer 5

#define producer 5

// 緩衝區最大數目

#define buffer_size 10

pthread_mutex_t g_mutex;

pthread_cond_t g_cond;

typedef

struct st_buffer_t buffer_t;

buffer_t g_buff =,0

,0,0

};// 列印緩衝情況

void

print()

printf

("\n");

}void

*producer

(void

*arg)

// 生產

g_buff.in %

= buffer_size;

g_buff.buf[g_buff.in]=1

;printf

("prodcuer %d produce 1 in %d: "

, producer_id, g_buff.in)

;print()

; g_buff.in++

; g_buff.count++

;// 生產後傳送訊號喚醒消費者執行緒

pthread_cond_signal

(&g_cond)

;pthread_mutex_unlock

(&g_mutex);}

return

null;}

void

*consumer

(void

*arg)

// 消費

g_buff.out %

= buffer_size;

printf

("consumer %d consume %d in %d: "

, consumer_id, g_buff.buf[g_buff.out]

, g_buff.out)

; g_buff.buf[g_buff.out]=0

;print()

; g_buff.out++

; g_buff.count--

;// 消費後傳送訊號喚醒生產者執行緒

pthread_cond_signal

(&g_cond)

;pthread_mutex_unlock

(&g_mutex);}

return

null;}

intmain

(int argc,

char

*ar**)

if(i < consumer)

}for

(int i =

0, j =

0; i < consumer || j < producer; i++

, j++)if

(i < consumer)

}// 銷毀互斥鎖和條件變數

pthread_mutex_destroy

(&g_mutex)

;pthread_cond_destroy

(&g_cond)

;return0;

}

兩個訊號量,乙個empty表示可生產產品的數量,乙個full表示已生產產品的數量

生產者wait empty減一後,拿到互斥鎖,生產,釋放互斥鎖,post full加一

消費者wait full減一後,拿到互斥鎖,消費,釋放互斥鎖,post empty加一

#include

#include

#include

#include

#include

// 生產者消費者的數量

#define consumer 5

#define producer 5

// 緩衝區最大數目

#define buffer_size 10

pthread_mutex_t g_mutex;

sem_t g_empty_sem;

sem_t g_full_sem;

typedef

struct st_buffer_t buffer_t;

buffer_t g_buff =,0

,0,0

};// 列印緩衝情況

void

print()

printf

("\n");

}void

*producer

(void

*arg)

return

null;}

void

*consumer

(void

*arg)

return

null;}

intmain

(int argc,

char

*ar**)

if(i < consumer)

}for

(int i =

0, j =

0; i < consumer || j < producer; i++

, j++)if

(i < consumer)

}// 銷毀互斥鎖和條件變數

pthread_mutex_destroy

(&g_mutex)

;sem_destroy

(&g_empty_sem)

;sem_destroy

(&g_full_sem)

;return0;

}

訊號量和條件變數 對比

多個執行緒在讀寫某個共享資料 全域性變數等 時必須通過某種方法實現共享資料的互斥訪問或者同步訪問 例如執行緒 b 等待執行緒 a 的結果以繼續執行 其中,訊號量是一種最常見的方法。訊號量是一種約定機制 在共享資源的互斥訪問中,它約定當乙個執行緒獲得訊號量 wait 後,其他執行緒不可以再次獲得該訊號...

執行緒同步 條件變數和訊號量

上一節提到了執行緒互斥和同步的概念,並且給出了兩種用於解決共享資源互斥的利器 互斥鎖和讀寫鎖。那麼本節將介紹兩種用於解決執行緒同步的概念 條件變數和訊號量。一.條件變數 1.基本概念 互斥鎖的缺點是它只有兩種狀態 鎖定和非鎖定。而條件變數通過允許執行緒阻塞和等待另乙個執行緒傳送訊號的方法彌補了互斥鎖...

多執行緒 互斥量 訊號量和條件變數

通常用於互斥訪問 pthread mutex t m mutex pthread mutex intit m mutex,null pthread mutex lock m mutex pthread mutex unlock m mutex pthread mutex destory m mute...