Created
June 20, 2015 09:51
-
-
Save callerobertsson/fa4b6939305be6efb8a0 to your computer and use it in GitHub Desktop.
Golang: Playing with a queue channel
This file contains 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 ( | |
"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