Using slice and conditional variables to implement a simple multi-producer multi-consumer queue
Source: Internet
Author: User
# using slice and conditional variables to implement a simple multi-producer multi-consumer Queue # # [Source Blog address] (https://github.com/Chasiny/Blog/blob/master/blog/go/%E4%BD%BF%E7%94% a8slice%e5%92%8c%e6%9d%a1%e4%bb%b6%e5%8f%98%e9%87%8f%e5%ae%9e%e7%8e%b0%e4%b8%80%e4%b8%aa%e7%ae%80%e5%8d%95%e7% 9A%84%E5%A4%9A%E7%94%9F%E4%BA%A7%E8%80%85%E5%A4%9A%E6%B6%88%E8%B4%B9%E8%80%85%E9%98%9F%E5%88%97.MD) # # [Project Code] ( Https://github.com/Chasiny/Blog/tree/master/code/go/message_queue) # # Design Requirements * Multi-producer, multi-consumer * When the buffer is full at the time of production, write blocking * consumption if the buffer is empty, Read Wait # # # structure first defines the queue structure "' Gotype MessageQueue struct {msgdata []interface{}//buffer len int32//buffer length Readpos int32// Read the pointer to Readmutex sync. mutex//read lock Writepos int32//writes the pointer to Writemutex sync. mutex//write lock Emptycond *sync. The cond//buffer is an empty condition variable Fullcond *sync. cond//buffer is full condition variable} ' ' The buffer used here is a ring queue # # # Write Method (Put) ' Gofunc (MQ *messagequeue) Put (in interface{}) {//First get write lock, The priority of all writes is the same as Mq.writeMutex.Lock () defer mq.writeMutex.Unlock ()//Determine if the buffer is full mq.fullcond.l.lock () defer Mq.fullcond.l.unlock () for (mq.writepos+1)%mq.len = = Mq.readpos {//buffer is full, waiting for consumer to consume the notification buffer with data being fetched mq.fullCond.Wait()}//writes a data mq.msgdata[mq.writepos] = Inmq.writepos = (mq.writepos + 1)% mq.len//notifies the consumer that there is already a buffer with data mq.emptyCond.Signal ()} ' # # # Read method (Get) ' Gofunc (MQ *messagequeue) Get () (out interface{}) {//Get read lock, read priority is the same mq.readMutex.Lock () defer Mq.readMutex.Unlock ()//Determine if the buffer is empty mq.emptycond.l.lock () defer mq.emptycond.l.unlock () for mq.writepos = = Mq.readpos {// Buffer is empty, wait for producer notification buffer to have data deposited mq.emptyCond.Wait ()}//read out = mq.msgdata[(mq.readpos)%mq.len]mq.readpos = (mq.readpos + 1)% Mq.len//notifies the producer that there is space in the buffer mq.fullCond.Signal () return} ' # # # New Method (new) ' Gofunc 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),}} "' # # # length (len) ' Gofunc (MQ *messagequeue) Len () int32 {if Mq.writepos < Mq.readpos {return mq.writepos + Mq.len-mq.readpos}return Mq.writepos-mq.readpos} "145 reads
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.
A Free Trial That Lets You Build Big!
Start building with 50+ products and up to 12 months usage for Elastic Compute Service