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  

Contact Us

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

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.