Skip to content

Instantly share code, notes, and snippets.

@andradei
Created March 28, 2016 15:20
Show Gist options
  • Save andradei/1cbc1dbc2569a68cc5cd to your computer and use it in GitHub Desktop.
Save andradei/1cbc1dbc2569a68cc5cd to your computer and use it in GitHub Desktop.
The Daily Walk - Go Concurrency Exercise
package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
var (
alarmTime = 60
rngToGetReady = [2]int{60, 90}
rngToPutShoes = [2]int{35, 45}
)
func getTime(timeRange [2]int) int {
// Always re-seed to get non-deterministic generated number.
// Use UnixNano() instead of Unix() because these methods are called too close to each other,
// practically being indistinguishable in time delta in seconds. NanoSeconds are not too close
// though, making its use more suitable here.
rand.Seed(time.Now().UnixNano())
// Get a time duration in the given range.
duration := rand.Intn(timeRange[1]-timeRange[0]+1) + timeRange[0]
return duration
}
func armAlarm(a chan bool) {
time.Sleep(time.Duration(60) * time.Second)
a <- true
}
func main() {
var wg sync.WaitGroup
alarm := make(chan bool)
startTime := time.Now()
gettingReady := func(name string) {
fmt.Println(name, "started getting ready.")
duration := getTime(rngToGetReady)
time.Sleep(time.Duration(duration) * time.Second)
fmt.Println(name, "spent", duration, "seconds getting ready.")
wg.Done()
}
putShoe := func(name string) {
fmt.Println(name, "started putting shoe.")
duration := getTime(rngToPutShoes)
time.Sleep(time.Duration(duration) * time.Second)
fmt.Println(name, "spent", duration, "putting on shoe.")
wg.Done()
}
fmt.Println("Let's go for a walk!")
wg.Add(2)
go gettingReady("Alice")
go gettingReady("Bob")
wg.Wait()
fmt.Println("\nArming alarm.\n")
// Re-add two more "things to wait".
wg.Add(2)
go armAlarm(alarm)
go putShoe("Alice")
go putShoe("Bob")
wg.Wait()
<-alarm
fmt.Println(time.Now().Sub(startTime))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment