生產者消費者模型,它是乙個多執行緒場景中的典型應用,應用廣泛,完成某些操作的時候,需要一些資料,這樣的資料可能由專門的執行緒/程序產生,在由專門的執行緒/程序使用。
生產者消費者模型,它需要乙個交易場所(儲存資料的地方,可能是乙個佇列,也可能是乙個棧,或者其他資料結構)。生產者負責生產資料,把資料放到交易場所中,消費者負責消費資料,把資料衝交易場所中取出。
生產者與生產者之間是互斥關係。
消費者與消費者之間是互斥關係。
生產者與消費者之間是同步和互斥關係。
首先我們只有互斥鎖來模擬這個創景
#include
#include
#include
#include
#include
using
namespace std;
//只加上了互斥鎖,保證了生產者之間,消費者之間的互斥
//實現乙個生產者消費者模型
//首先要有乙個交易場所
vector<
int> data;
//全域性
pthread_mutex_t mt;
void
*product
(void
* arg)
return
null;}
void
*consum
(void
* arg)
pthread_mutex_unlock
(&mt)
;usleep
(123123);
}return
null;}
intmain()
這份**只是保證了生產者與生產者之間的互斥關係,消費者與消費者之間的互斥關係。沒***生產者與消費者之間的同步,可能會出現執行緒餓死。為了解決這個問題,我們加上條件變數。
#include
//增加同步!!!
#include
#include
#include
using
namespace std;
//實現乙個生產者消費者模型
//首先要有乙個交易場所
vector<
int> data;
//全域性
pthread_mutex_t mt;
pthread_cond_t cond;
void
*product
(void
* arg)
return
null;}
void
*consum
(void
* arg)
int result=data.
back()
;//如果為空記憶體訪問越界
data.
pop_back()
;printf
("result=%d\n"
,result)
;pthread_mutex_unlock
(&mt)
;usleep
(123123);
}return
null;}
intmain()
增加同步的意義是,避免了消費者頻繁的空轉,防止執行緒飢餓,減少排程的開銷。
同步與互斥不一定非得用互斥鎖和條件變數來實現,可以用訊號量來模擬乙個阻塞佇列blockingqueue來完成。
訊號量本質是乙個計數器,表示可用資源的個數。
//初始化訊號量
intsem_init()
;//銷毀訊號量
intsem_destroy()
//等待訊號量
intsem_wait()
//發布訊號量
intsem_post
()
使用訊號量時,sem_wait()操作用來申請資源,計數器-1,sem_post()操作來釋放資源,計數器+1,當計算器為0時,再去操作就會發生阻塞。訊號量這個計算操作是原子的。
//hpp 宣告與實現在一起用hpp
#pragma once
///實現阻塞佇列的**!!!!!!!
#include
#include
#include
#include
#include
//阻塞佇列:一種常見的資料結構,執行緒安全版本的佇列
//一般blockingqueue,都要求長度有上限
//如果隊列為空,去執行pop會阻塞
//如果佇列滿了,去執行push也會阻塞
//訊號量表示互斥比較簡單,但是表示同步比較複雜
//訊號量表示可用資源的個數
//乙個訊號量表示當前佇列中元素的個數
//另乙個訊號量表示當前佇列中空格的個數
//插入元素,消耗空格資源,釋放元素資源,
//刪除元素就是消耗了乙個元素資源,釋放了乙個空格資源
//如果用訊號量表示互斥,p操作和v操作在同乙個函式
///如果用訊號量表示同步,p操作和v操作在不同的函式中
//訊號量這個計算器的+1 -1是原子的
template
<
typename t>
class
blockingqueue
~blockingqueue()
void
push
(const t& data)
//data表示出佇列的這個元素
void
pop(t* data)
//輸出型引數
private
: std::vector queue_;
int head_;
int tail_;
int size_;
int max_size_;
sem_t lock_;
//可以用二元訊號量表示互斥鎖 (非0即1)表示互斥鎖
sem_t elem_;
//可用元素個數
sem_t blank_;
//可用空格個數
};
///用blockingqueue實現乙個簡單的生產者消費者模型
#include
"blockingqueue.hpp"
blockingqueue <
int>
queue
(100);
void
*product
(void
* arg)
return
null;}
void
*consume
(void
* arg)
return
null;}
//程序間通訊 管道 本質就是乙個blockingqueue
intmain()
生產者消費者模型
1.生產者消費者問題 producer consumer 有限緩衝,多執行緒同步。生產者執行緒和消費者執行緒共享固定大小緩衝區。2.關鍵是保證生產者不會再緩衝區滿時加入資料,消費者不會在緩衝區空時消耗資料。3.解決辦法 讓生產者在緩衝區滿時休眠,等下次消費者消耗緩衝區中的資料的時候,生產者才能被喚醒...
生產者消費者模型
生產者與消費者 3,2,1 三種關係 生產者與消費者 互斥,同步 消費者與消費者 互斥 生產者與生產者 互斥 條件變數 int pthread cond destroy pthread cond t cond int pthread cond init pthread cond t restrict...
生產者消費者模型
當佇列滿時,生產者需要等待佇列有空間才能繼續往裡面放入商品,而在等待的期間內,生產者必須釋放對臨界資源 即佇列 的占用權。因為生產者如果不釋放對臨界資源的占用權,那麼消費者就無法消費佇列中的商品,就不會讓佇列有空間,那麼生產者就會一直無限等待下去。因此,一般情況下,當佇列滿時,會讓生產者交出對臨界資...