mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2025-09-12 22:52:05 +00:00
good good study, day day up!
This commit is contained in:
89
vendor/gopl.io/ch8/cake/cake.go
generated
vendored
Normal file
89
vendor/gopl.io/ch8/cake/cake.go
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
|
||||
// See page 234.
|
||||
|
||||
// Package cake provides a simulation of
|
||||
// a concurrent cake shop with numerous parameters.
|
||||
//
|
||||
// Use this command to run the benchmarks:
|
||||
// $ go test -bench=. gopl.io/ch8/cake
|
||||
package cake
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Shop struct {
|
||||
Verbose bool
|
||||
Cakes int // number of cakes to bake
|
||||
BakeTime time.Duration // time to bake one cake
|
||||
BakeStdDev time.Duration // standard deviation of baking time
|
||||
BakeBuf int // buffer slots between baking and icing
|
||||
NumIcers int // number of cooks doing icing
|
||||
IceTime time.Duration // time to ice one cake
|
||||
IceStdDev time.Duration // standard deviation of icing time
|
||||
IceBuf int // buffer slots between icing and inscribing
|
||||
InscribeTime time.Duration // time to inscribe one cake
|
||||
InscribeStdDev time.Duration // standard deviation of inscribing time
|
||||
}
|
||||
|
||||
type cake int
|
||||
|
||||
func (s *Shop) baker(baked chan<- cake) {
|
||||
for i := 0; i < s.Cakes; i++ {
|
||||
c := cake(i)
|
||||
if s.Verbose {
|
||||
fmt.Println("baking", c)
|
||||
}
|
||||
work(s.BakeTime, s.BakeStdDev)
|
||||
baked <- c
|
||||
}
|
||||
close(baked)
|
||||
}
|
||||
|
||||
func (s *Shop) icer(iced chan<- cake, baked <-chan cake) {
|
||||
for c := range baked {
|
||||
if s.Verbose {
|
||||
fmt.Println("icing", c)
|
||||
}
|
||||
work(s.IceTime, s.IceStdDev)
|
||||
iced <- c
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Shop) inscriber(iced <-chan cake) {
|
||||
for i := 0; i < s.Cakes; i++ {
|
||||
c := <-iced
|
||||
if s.Verbose {
|
||||
fmt.Println("inscribing", c)
|
||||
}
|
||||
work(s.InscribeTime, s.InscribeStdDev)
|
||||
if s.Verbose {
|
||||
fmt.Println("finished", c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Work runs the simulation 'runs' times.
|
||||
func (s *Shop) Work(runs int) {
|
||||
for run := 0; run < runs; run++ {
|
||||
baked := make(chan cake, s.BakeBuf)
|
||||
iced := make(chan cake, s.IceBuf)
|
||||
go s.baker(baked)
|
||||
for i := 0; i < s.NumIcers; i++ {
|
||||
go s.icer(iced, baked)
|
||||
}
|
||||
s.inscriber(iced)
|
||||
}
|
||||
}
|
||||
|
||||
// work blocks the calling goroutine for a period of time
|
||||
// that is normally distributed around d
|
||||
// with a standard deviation of stddev.
|
||||
func work(d, stddev time.Duration) {
|
||||
delay := d + time.Duration(rand.NormFloat64()*float64(stddev))
|
||||
time.Sleep(delay)
|
||||
}
|
Reference in New Issue
Block a user