Skip to content

Instantly share code, notes, and snippets.

@aldy505
Created November 25, 2021 15:11
Show Gist options
  • Save aldy505/f8e83b6fbab624c8c3907be6d07ed843 to your computer and use it in GitHub Desktop.
Save aldy505/f8e83b6fbab624c8c3907be6d07ed843 to your computer and use it in GitHub Desktop.
Simple yet annoying demonstration of concurrency stuffs in Go
package main
import (
"fmt"
"log"
"sync"
"time"
)
func main() {
withMachine := Machines{}
orders := make(chan int, 12)
for i := 0; i < 12; i++ {
go withMachine.makeCoffee(orders, i+1)
}
fmt.Println("Order completed for order no.", <-orders)
fmt.Println("Order completed for order no.", <-orders)
fmt.Println("Order completed for order no.", <-orders)
fmt.Println("Order completed for order no.", <-orders)
fmt.Println("Order completed for order no.", <-orders)
fmt.Println("Order completed for order no.", <-orders)
fmt.Println("Order completed for order no.", <-orders)
fmt.Println("Order completed for order no.", <-orders)
fmt.Println("Order completed for order no.", <-orders)
fmt.Println("Order completed for order no.", <-orders)
fmt.Println("Order completed for order no.", <-orders)
fmt.Println("Order completed for order no.", <-orders)
fmt.Println("Espresso machine, time used:", withMachine.EspressoMachine.TimeUsed)
fmt.Println("Beans grinder, time used:", withMachine.BeansGrinder.TimeUsed)
}
type EspressoMachine struct {
sync.Mutex
InUse bool
TimeUsed int
}
type BeansGrinder struct {
sync.Mutex
InUse bool
TimeUsed int
}
type Machines struct {
BeansGrinder
EspressoMachine
}
func (m *Machines) makeCoffee(orders chan int, number int) {
log.Printf("Got order number %d\n", number)
var wg sync.WaitGroup
wg.Add(3)
prepare := make(chan bool, 2)
go prepareGlass(wg, prepare, number)
go m.BeansGrinder.roastBeans(wg, prepare, number)
<-prepare
<-prepare
close(prepare)
go m.EspressoMachine.makeEspresso(wg, number)
orders <- number
wg.Wait()
}
func prepareGlass(wg sync.WaitGroup, status chan bool, number int) {
log.Printf("Preparing glass for order no. %d\n", number)
time.Sleep(time.Second*1)
wg.Done()
status <- true
}
func (b *BeansGrinder) roastBeans(wg sync.WaitGroup, status chan bool, number int) {
b.Lock()
defer b.Unlock()
log.Printf("Roasting beans for order no. %d\n", number)
b.InUse = true
time.Sleep(time.Second*2)
b.InUse = false
b.TimeUsed++
wg.Done()
status <- true
}
func (e *EspressoMachine) makeEspresso(wg sync.WaitGroup, number int) {
e.Lock()
defer e.Unlock()
log.Printf("Making espresso for order no. %d\n", number)
e.InUse = true
time.Sleep(time.Second*3)
e.InUse = false
e.TimeUsed++
wg.Done()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment