Skip to content

Instantly share code, notes, and snippets.

@itarato
Created December 9, 2016 08:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save itarato/b9da975b2b197acbc6ea89844ef48dce to your computer and use it in GitHub Desktop.
Save itarato/b9da975b2b197acbc6ea89844ef48dce to your computer and use it in GitHub Desktop.
Queue that can handle pop wait.
package main
import (
"fmt"
"sync"
"time"
)
type ElemType int32
// LINK ///////////////////////////////////////////////////////////////////////
type Link struct {
Key ElemType
Next *Link
}
func NewLink(key ElemType) *Link {
return &Link{Key: key}
}
// QUEUE //////////////////////////////////////////////////////////////////////
type Queue struct {
Head *Link
Mutex sync.Mutex
PushChan chan bool
}
func NewQueue() *Queue {
q := &Queue{}
q.PushChan = make(chan bool)
return q
}
func (q *Queue) push(key ElemType) {
q.Mutex.Lock()
defer q.Mutex.Unlock()
l := NewLink(key)
if q.Head == nil {
q.Head = l
} else {
prev := q.Head
for prev.Next != nil {
prev = prev.Next
}
prev.Next = l
}
if q.size() == 1 {
q.PushChan <- true
}
}
func (q *Queue) pop() ElemType {
if q.Head == nil {
<-q.PushChan
}
q.Mutex.Lock()
defer q.Mutex.Unlock()
if q.Head == nil {
panic("Empty queue")
}
key := q.Head.Key
q.Head = q.Head.Next
return key
}
func (q *Queue) size() uint32 {
var size uint32 = 0
l := q.Head
for l != nil {
l = l.Next
size++
}
return size
}
// JOB ////////////////////////////////////////////////////////////////////////
func produce(n uint32, q *Queue) {
var i uint32
for i = 0; i < n; i++ {
fmt.Printf("> Pop new element: %d\n", i)
q.push(ElemType(i))
time.Sleep(time.Millisecond * 1)
}
}
func consume(n uint32, q *Queue) {
var i uint32
for i = 0; i < n; i++ {
fmt.Printf("< Popped: %d\n", q.pop())
}
}
// MAIN ///////////////////////////////////////////////////////////////////////
func main() {
var wg sync.WaitGroup
q := NewQueue()
wg.Add(1)
go func() {
defer wg.Done()
consume(16, q)
}()
wg.Add(1)
go func() {
defer wg.Done()
produce(16, q)
}()
wg.Wait()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment