生產者消費者模型

2021-09-27 10:01:45 字數 3470 閱讀 6758

生產者消費者模型,它是乙個多執行緒場景中的典型應用,應用廣泛,完成某些操作的時候,需要一些資料,這樣的資料可能由專門的執行緒/程序產生,在由專門的執行緒/程序使用。

生產者消費者模型,它需要乙個交易場所(儲存資料的地方,可能是乙個佇列,也可能是乙個棧,或者其他資料結構)。生產者負責生產資料,把資料放到交易場所中,消費者負責消費資料,把資料衝交易場所中取出。

生產者與生產者之間是互斥關係。

消費者與消費者之間是互斥關係。

生產者與消費者之間是同步和互斥關係。

首先我們只有互斥鎖來模擬這個創景

#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...

生產者消費者模型

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