65 lines
1.5 KiB
Go
65 lines
1.5 KiB
Go
package main
|
|
|
|
import (
|
|
"log"
|
|
"math/rand"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
func worker(part string, completed chan string) {
|
|
log.Println(part, "worker running")
|
|
for {
|
|
select {
|
|
case <-start:
|
|
log.Println(part, "worker begins part")
|
|
time.Sleep(time.Duration(rand.Int63n(1e6)))
|
|
p := strings.ToLower(part)
|
|
log.Println(part, "worker completed", p)
|
|
completed <- p
|
|
<-reset
|
|
wg.Done()
|
|
case <-done:
|
|
log.Println(part, "worker stopped")
|
|
wg.Done()
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
var (
|
|
partList = []string{"A", "B", "C", "D"}
|
|
nAssemblies = 3
|
|
start = make(chan int)
|
|
done = make(chan int)
|
|
reset chan int
|
|
wg sync.WaitGroup
|
|
)
|
|
|
|
func main() {
|
|
rand.Seed(time.Now().UnixNano())
|
|
completed := make([]chan string, len(partList))
|
|
for i, part := range partList {
|
|
completed[i] = make(chan string)
|
|
go worker(part, completed[i])
|
|
}
|
|
for c := 1; c <= nAssemblies; c++ {
|
|
log.Println("begin assembly cycle", c)
|
|
reset = make(chan int)
|
|
close(start)
|
|
a := ""
|
|
for _, c := range completed {
|
|
a += <-c
|
|
}
|
|
log.Println(a, "assembled. cycle", c, "complete")
|
|
wg.Add(len(partList))
|
|
start = make(chan int)
|
|
close(reset)
|
|
wg.Wait()
|
|
}
|
|
wg.Add(len(partList))
|
|
close(done)
|
|
wg.Wait()
|
|
}
|