Created
January 29, 2016 08:28
-
-
Save paddycarver/e2589d969025bda892bd to your computer and use it in GitHub Desktop.
Whippersnapper.com concurrency exercises
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 ( | |
"fmt" | |
"math/rand" | |
"sync" | |
"time" | |
) | |
func useComputer(tourists chan int, done chan struct{}) { | |
for tourist := range tourists { | |
fmt.Println("Tourist", tourist, "is online.") | |
duration := time.Duration(rand.Intn(15)) * time.Second | |
time.Sleep(duration) | |
fmt.Printf("Tourist %d is done, having spent %d minutes online.\n", tourist, duration/time.Second) | |
} | |
close(done) | |
} | |
func waitForComputer(tourists chan int, tourist int, wg *sync.WaitGroup) { | |
select { | |
case tourists <- tourist: | |
default: | |
fmt.Println("Tourist", tourist, "waiting for turn.") | |
} | |
tourists <- tourist | |
wg.Done() | |
} | |
func main() { | |
rand.Seed(time.Now().Unix()) | |
tourists := make(chan int) | |
comp1 := make(chan struct{}) | |
comp2 := make(chan struct{}) | |
comp3 := make(chan struct{}) | |
comp4 := make(chan struct{}) | |
comp5 := make(chan struct{}) | |
comp6 := make(chan struct{}) | |
comp7 := make(chan struct{}) | |
comp8 := make(chan struct{}) | |
go useComputer(tourists, comp1) | |
go useComputer(tourists, comp2) | |
go useComputer(tourists, comp3) | |
go useComputer(tourists, comp4) | |
go useComputer(tourists, comp5) | |
go useComputer(tourists, comp6) | |
go useComputer(tourists, comp7) | |
go useComputer(tourists, comp8) | |
var wg sync.WaitGroup | |
for i := 1; i <= 25; i++ { | |
wg.Add(1) | |
go waitForComputer(tourists, i, &wg) | |
} | |
wg.Wait() | |
close(tourists) | |
<-comp1 | |
<-comp2 | |
<-comp3 | |
<-comp4 | |
<-comp5 | |
<-comp6 | |
<-comp7 | |
<-comp8 | |
fmt.Println("The place is empty, let's close up and go to the beach!") | |
} |
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 ( | |
"fmt" | |
"math/rand" | |
"sync" | |
"time" | |
) | |
func merge(chans ...<-chan string) <-chan string { | |
var wg sync.WaitGroup | |
out := make(chan string) | |
output := func(c <-chan string) { | |
for n := range c { | |
out <- n | |
} | |
wg.Done() | |
} | |
wg.Add(len(chans)) | |
for _, c := range chans { | |
go output(c) | |
} | |
go func() { | |
wg.Wait() | |
close(out) | |
}() | |
return out | |
} | |
func serveFood(name string, platter chan string) { | |
numFood := rand.Intn(5) + 5 | |
for i := 0; i < numFood; i++ { | |
platter <- name | |
} | |
close(platter) | |
} | |
func eat(name string, table <-chan string, plate chan struct{}) { | |
for morsel := range table { | |
fmt.Println(name, "is enjoying some", morsel) | |
delay := time.Duration(rand.Intn(15)) * time.Second | |
time.Sleep(delay) | |
} | |
close(plate) | |
} | |
func main() { | |
rand.Seed(time.Now().Unix()) | |
fmt.Println("Bon appétit") | |
chorizo := make(chan string) | |
chopitos := make(chan string) | |
pimientos := make(chan string) | |
croquetas := make(chan string) | |
patatas := make(chan string) | |
go serveFood("chorizo", chorizo) | |
go serveFood("chopitos", chopitos) | |
go serveFood("pimientos de padrón", pimientos) | |
go serveFood("croquetas", croquetas) | |
go serveFood("patatas bravas", patatas) | |
table := merge(chorizo, chopitos, pimientos, croquetas, patatas) | |
alice := make(chan struct{}) | |
bob := make(chan struct{}) | |
charlie := make(chan struct{}) | |
dave := make(chan struct{}) | |
go eat("Alice", table, alice) | |
go eat("Bob", table, bob) | |
go eat("Charlie", table, charlie) | |
go eat("Dave", table, dave) | |
<-alice | |
<-bob | |
<-charlie | |
<-dave | |
fmt.Println("That was delicious!") | |
} |
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 ( | |
"fmt" | |
"math/rand" | |
"time" | |
) | |
func getReady(name string, done chan time.Duration) { | |
fmt.Printf("%s started getting ready\n", name) | |
timeGettingReady := time.Second * time.Duration(rand.Intn(30)+60) | |
time.Sleep(timeGettingReady) | |
done <- timeGettingReady | |
} | |
func resolveReady(aliceDur, bobDur chan time.Duration) { | |
select { | |
case dur := <-aliceDur: | |
fmt.Printf("Alice spent %d seconds getting ready\n", dur/time.Second) | |
case dur := <-bobDur: | |
fmt.Printf("Bob spent %d seconds getting ready\n", dur/time.Second) | |
} | |
} | |
func armAlarm(done chan struct{}) { | |
fmt.Println("Alarm is counting down.") | |
time.Sleep(60 * time.Second) | |
fmt.Println("Alarm is armed.") | |
close(done) | |
} | |
func putShoesOn(name string, done chan time.Duration) { | |
fmt.Printf("%s started putting on shoes\n", name) | |
timePuttingOnShoes := time.Second * time.Duration(rand.Intn(10)+35) | |
time.Sleep(timePuttingOnShoes) | |
done <- timePuttingOnShoes | |
} | |
func resolveShoes(aliceShoes, bobShoes chan time.Duration) { | |
select { | |
case dur := <-aliceShoes: | |
fmt.Printf("Alice spent %d seconds putting on shoes\n", dur/time.Second) | |
case dur := <-bobShoes: | |
fmt.Printf("Bob spent %d seconds putting on shoes\n", dur/time.Second) | |
} | |
} | |
func main() { | |
rand.Seed(time.Now().Unix()) | |
fmt.Println("Let's go for a walk!") | |
aliceReady, bobReady := make(chan time.Duration), make(chan time.Duration) | |
go getReady("Alice", aliceReady) | |
go getReady("Bob", bobReady) | |
// we want both to be ready, but don't care the order | |
resolveReady(aliceReady, bobReady) | |
resolveReady(aliceReady, bobReady) | |
fmt.Println("Arming alarm.") | |
alarmDone := make(chan struct{}) | |
go armAlarm(alarmDone) | |
aliceShoes, bobShoes := make(chan time.Duration), make(chan time.Duration) | |
go putShoesOn("Alice", aliceShoes) | |
go putShoesOn("Bob", bobShoes) | |
resolveShoes(aliceShoes, bobShoes) | |
resolveShoes(aliceShoes, bobShoes) | |
fmt.Println("Exiting and locking the door.") | |
<-alarmDone | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment