1package main
2
3import (
4 "fmt"
5 "runtime"
6)
7
8func main() {
9 goroutine := runtime.NumCPU()
10 chanSlice := make([]chan struct{}, 0)
11 chanExit := make(chan struct{}, 1)
12
13 for i := 0; i < goroutine; i++ {
14 chanSlice = append(chanSlice, make(chan struct{}, 1))
15 }
16
17 max := 100
18 num := 0
19
20 fmt.Println("runtime.NumCPU(): ", runtime.NumCPU())
21
22 for i := 0; i < goroutine; i++ {
23 go func(x int) {
24 for {
25 <-chanSlice[x]
26 num++
27 fmt.Println("goroutine: ", x, " chan: ", chanSlice[x], " num: ", num)
28
29 if num == max {
30 chanExit <- struct{}{}
31 break
32 }
33
34 chanSlice[(x+1)%goroutine] <- struct{}{}
35 }
36 }(i)
37 }
38
39 chanSlice[0] <- struct{}{}
40
41 select {
42 case <-chanExit:
43 fmt.Println("exit")
44 }
45
46 fmt.Println("goroutine: ", runtime.NumGoroutine())
47}
改造下:
1package main
2
3import (
4 "fmt"
5 "runtime"
6 "sync"
7)
8
9func main() {
10 var wg sync.WaitGroup
11 goroutine := runtime.NumCPU()
12 chanSlice := make([]chan struct{}, 0)
13 chanExit := make(chan struct{}, 1)
14
15 for i := 0; i < goroutine; i++ {
16 chanSlice = append(chanSlice, make(chan struct{}, 1))
17 }
18
19 max := 100
20 num := 0
21
22 fmt.Println("runtime.NumCPU(): ", runtime.NumCPU())
23
24 for i := 0; i < goroutine; i++ {
25 wg.Add(1)
26 go func(x int) {
27 defer wg.Done()
28 defer fmt.Println("exit goroutine: ", x)
29 for {
30 select {
31 case <-chanExit:
32 // close the next goroutine
33 chanExit <- struct{}{}
34 return
35
36 case <-chanSlice[x]:
37 num++
38 fmt.Println("goroutine: ", x, " chan: ", chanSlice[x], " num: ", num)
39
40 if num == max {
41 chanExit <- struct{}{}
42 break
43 }
44 chanSlice[(x+1)%goroutine] <- struct{}{}
45 }
46 }
47 }(i)
48 }
49
50 // start
51 chanSlice[0] <- struct{}{}
52 wg.Wait()
53
54 fmt.Println("goroutine: ", runtime.NumGoroutine())
55}