1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
| const ( idCheckTmCost = 60 bodyCheckTmCost = 120 xRayCheckTmCost = 180 )
func idCheck(id string) int { time.Sleep(time.Millisecond * time.Duration(idCheckTmCost)) print("\tgoroutine-", id, "-idCheck: idCheck ok\n") return idCheckTmCost }
func bodyCheck(id string) int { time.Sleep(time.Millisecond * time.Duration(bodyCheckTmCost)) print("\tgoroutine-", id, "-bodyCheck: bodyCheck ok\n") return bodyCheckTmCost }
func xRayCheck(id string) int { time.Sleep(time.Millisecond * time.Duration(xRayCheckTmCost)) print("\tgoroutine-", id, "-xRayCheck: xRayCheck ok\n") return xRayCheckTmCost }
func start(id string, f func(string) int, next chan<- struct{}) (chan<- struct{}, chan<- struct{}, <-chan int) { queue := make(chan struct{}, 10) quit := make(chan struct{}) result := make(chan int)
go func() { total := 0 for { select { case <-quit: result <- total return case v := <-queue: total += f(id) if next != nil { next <- v } } }
}() return queue, quit, result }
func newAirportSecurityCheckChannel(id string, queue <-chan struct{}) { go func(id string) { print("goroutine-", id, ": airportSecurityCheckChannel is ready...\n") queue3, quit3, result3 := start(id, xRayCheck, nil)
queue2, quit2, result2 := start(id, bodyCheck, queue3)
queue1, quit1, result1 := start(id, idCheck, queue2)
for { select { case v, ok := <-queue: if !ok { close(quit1) close(quit2) close(quit3) total := max(<-result1, <-result2, <-result3) print("goroutine-", id, ": airportSecurityCheckChannel time cost:", total, "\n") print("goroutine-", id, ": airportSecurityCheckChannel closed\n") return } queue1 <- v } } }(id) }
func max(args ...int) int { n := 0 for _, v := range args { if v > n { n = v } } return n }
func main() { passengers := 30 queue := make(chan struct{}, 30) newAirportSecurityCheckChannel("channel1", queue) newAirportSecurityCheckChannel("channel2", queue) newAirportSecurityCheckChannel("channel3", queue)
time.Sleep(5 * time.Second) for i := 0; i < passengers; i++ { queue <- struct{}{} } time.Sleep(5 * time.Second) close(queue) time.Sleep(1000 * time.Second) }
|