Created
December 9, 2016 08:14
-
-
Save itarato/b9da975b2b197acbc6ea89844ef48dce to your computer and use it in GitHub Desktop.
Queue that can handle pop wait.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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