使用slice和條件變數實現一個簡單的多生產者多消費者佇列
使用 slice 和條件變數實現一個簡單的多生產者多消費者佇列
設計要求
- 多生產者,多消費者
- 生產時若緩衝區以滿,則寫入阻塞
- 消費時若緩衝區為空,則讀取等待
設計思路
結構體
首先定義佇列結構體
type MessageQueue struct {
msgdata []interface{} //緩衝區
len int32 //緩衝區長度
readPos int32 //讀取指向的指標
readMutex sync.Mutex //讀取鎖
writePos int32 //寫入指向的指標
writeMutex sync.Mutex //寫入鎖
emptyCond *sync.Cond //緩衝區為空條件變數
fullCond *sync.Cond //緩衝區為滿條件變數
}
這裡使用的緩衝區是一個環形佇列
寫入的方法 (Put)
func (mq *MessageQueue) Put(in interface{}) {
//首先獲取寫鎖,所有寫入的優先順序是一樣的
mq.writeMutex.Lock()
defer mq.writeMutex.Unlock()
//判斷緩衝區是否為滿
mq.fullCond.L.Lock()
defer mq.fullCond.L.Unlock()
for (mq.writePos+1)%mq.len == mq.readPos {
//緩衝區為滿,等待消費者消費的通知緩衝區有資料被取出
mq.fullCond.Wait()
}
//寫入一個資料
mq.msgdata[mq.writePos] = in
mq.writePos = (mq.writePos + 1) % mq.len
//通知消費者已經有緩衝區有資料了
mq.emptyCond.Signal()
}
讀取的方法 (Get)
func (mq *MessageQueue) Get() (out interface{}) {
//獲取讀鎖,讀取的優先順序也是一樣的
mq.readMutex.Lock()
defer mq.readMutex.Unlock()
//判斷緩衝區是否為空
mq.emptyCond.L.Lock()
defer mq.emptyCond.L.Unlock()
for mq.writePos == mq.readPos {
//緩衝區為空,等待生產者通知緩衝區有資料存入
mq.emptyCond.Wait()
}
//讀取
out = mq.msgdata[(mq.readPos)%mq.len]
mq.readPos = (mq.readPos + 1) % mq.len
//通知生產者已經有緩衝區有空間了
mq.fullCond.Signal()
return
}
New 方法 (New)
func NewMQ(len int32) *MessageQueue {
if len < 1 {
panic("new meg queue fail: len < 1")
return nil
}
l:=&sync.Mutex{}
return &MessageQueue{
msgdata: make([]interface{}, len+1),
len: len + 1,
readPos: 0,
writePos: 0,
emptyCond: sync.NewCond(l),
fullCond: sync.NewCond(l),
}
}
長度 (Len)
func (mq *MessageQueue) Len() int32 {
if mq.writePos < mq.readPos {
return mq.writePos + mq.len - mq.readPos
}
return mq.writePos - mq.readPos
}
更多原創文章乾貨分享,請關注公眾號
- 加微信實戰群請加微信(註明:實戰群):gocnio
相關文章
- 使用Python佇列和多執行緒實現生產者消費者Python佇列執行緒
- Linux多執行緒消費者和生產者模型例項(互斥鎖和條件變數使用)Linux執行緒模型變數
- 阻塞佇列和生產者-消費者模式佇列模式
- 什麼是阻塞佇列?如何使用阻塞佇列來實現生產者-消費者模型?佇列模型
- 使用BlockQueue實現生產者和消費者模式BloC模式
- 使用Disruptor實現生產者和消費者模型模型
- Java實現生產者和消費者Java
- 生產者和消費者(.net實現)
- 用阻塞佇列實現一個生產者消費者模型?synchronized和lock有什麼區別?佇列模型synchronized
- Kafka 簡單實驗二(Python實現簡單生產者消費者)KafkaPython
- 多生產者-消費者中假死現象的處理
- Java多執行緒——生產者和消費者模式Java執行緒模式
- 十五、.net core(.NET 6)搭建RabbitMQ訊息佇列生產者和消費者的簡單方法MQ佇列
- 【RabbitMQ】生產者,消費者,通道,佇列,交換器和繫結MQ佇列
- rabbitMQ實戰生產者-交換機-佇列-消費者細談MQ佇列
- 關於Java多執行緒實現生產者和消費者的問題Java執行緒
- 多執行緒之生產者消費者執行緒
- PHP操作Beanstalkd佇列(2)生產者與消費者PHPBean佇列
- 母雞下蛋例項:多執行緒通訊生產者和消費者wait/notify和condition/await/signal條件佇列執行緒AI佇列
- 多執行緒併發如何高效實現生產者/消費者?執行緒
- 用Python多執行緒實現生產者消費者模式Python執行緒模式
- python 多執行緒實現生產者與消費者模型Python執行緒模型
- 用Go語言 實現一個簡單生產者消費者模型 ,如何做?Go模型
- python多執行緒+生產者和消費者模型+queue使用Python執行緒模型
- 使用pthread_mutex_t與條件變數pthread_cond_t的組合來實現生產者和消費者threadMutex變數
- 多執行緒下的生產者和消費者-BlockingQueue執行緒BloC
- Qt生產者消費者實驗(2):等待條件QWaitConditionQTAI
- Java多執行緒——生產者消費者示例Java執行緒
- 實戰Spring4+ActiveMQ整合實現訊息佇列(生產者+消費者)SpringMQ佇列
- Python並行程式設計(六):多執行緒同步之queue(佇列)實現生產者-消費者模型Python並行行程程式設計執行緒佇列模型
- Java實現生產者-消費者模型Java模型
- python中多程式消費者生產者問題Python
- Java多執行緒14:生產者/消費者模型Java執行緒模型
- 分享一個生產者-消費者的真實場景
- 訊號量實現生產者消費者(程式碼邏輯有問題,不適合多個消費者,不常用)
- 二、(LINUX 執行緒同步) 互斥量、條件變數以及生產者消費者問題Linux執行緒變數
- java實現生產者消費者問題Java
- C#多執行緒學習(三) 生產者和消費者C#執行緒