Skip to content

Instantly share code, notes, and snippets.

@callerobertsson
Created June 20, 2015 09:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save callerobertsson/fa4b6939305be6efb8a0 to your computer and use it in GitHub Desktop.
Save callerobertsson/fa4b6939305be6efb8a0 to your computer and use it in GitHub Desktop.
Golang: Playing with a queue channel
package main
import (
"bufio"
"fmt"
"math/rand"
"os"
"strconv"
"time"
)
const (
queueSize = 9
numberOfReaders = 3
)
var readerSleepInterval = struct{ min, max int }{0, 2}
var queue = make(chan int, queueSize)
var done = make(chan bool)
func main() {
fmt.Println("=== Playing with a simple queue ===")
fmt.Printf(" Queue size: %v\n", queueSize)
fmt.Printf(" Number of readers: %v\n", numberOfReaders)
fmt.Printf(" Reader sleep interval from %v to %v seconds\n", readerSleepInterval.min, readerSleepInterval.max)
fmt.Printf("Forking %v readers\n ", numberOfReaders)
for i := 0; i < numberOfReaders; i++ {
fmt.Printf("#%v ", i)
go queueReader(i)
}
fmt.Println("")
fmt.Println("Forking the Producer")
go queueProducer()
fmt.Println("Waiting for quit from the Producer")
<-done
fmt.Println("Done!")
}
// Producer will ask user to input number of items to put in queue
// If number exceeds the queue size, it hang until the queue can
// accept more items, then it will push more items on the queue
func queueProducer() {
reader := bufio.NewReader(os.Stdin)
for {
fmt.Printf("Number of items to add (quit to exit): ")
bytes, _, err := reader.ReadLine()
if err != nil {
fmt.Println(err.Error())
continue
}
val := string(bytes)
if val == "quit" {
done <- true
return
}
n, err := strconv.Atoi(val)
if err != nil {
fmt.Println("Enter a number, please!")
continue
}
for i := 0; i < n; i++ {
queue <- i
}
}
}
// Reader will read from queue and then pretend to process it for a
// random(ish) number of seconds.
func queueReader(n int) {
for {
val := <-queue
rsi := readerSleepInterval
s := rand.Intn(rsi.max-rsi.min) + rsi.min
fmt.Printf(" Reader #%v read %v from queue, processing for %v seconds\n", n, val, s)
time.Sleep(time.Duration(s) * time.Second)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment