在main函数中开启一个用于计算的goroutine, 为了让main方法知道什么时候计算完成了,在compute方法中传入一个channel参数,在main方法中取channel的值.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
func main() {
ch := make(chan int64)
go sum([]int64{1, 3, 4, 5, 6, 10}, ch)

fmt.Printf("sum = %d\n", <-ch)
}

func sum(numbers []int64, sum chan int64) {
total := int64(0)
for _, n := range numbers {
total += n
time.Sleep(time.Millisecond)
}

sum <- total
}

为了并发的计算一个切片中每个元素,重新得到一个新的切片。设置一个和切片同数量的chan 切片,每完成一个元素的计算,就给chan切片的元素发送一个信号,表示这个元素的值计算完成了。在main中,用for loop接受chan切片每个元素中发送的值, 保证全部切片元素的值计算都完成了。

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
type Empty interface{}

var empty Empty

func main() {
N := 10
data := make([]int64, N)
sem := make(chan Empty, N)
res := make([]int64, N)

rand.Seed(42)
for i := 0; i < N; i++ {
data[i] = rand.Int63n(100)
}

for i, n := range data {
go func(i int, n int64) {
fmt.Printf("calculating %d, %d\n", i, n)
res[i] = doSomeCalculate(i, n)
sem <- empty
}(i, n) // 每个goroutine需要的i, n都是不同的.
}

for i := 1; i <= N; i++ {
<-sem
}

fmt.Printf("after all calculation done!")
}

func doSomeCalculate(i int, n int64) int64 {
v := int64(i) * n
time.Sleep(100 * time.Millisecond)
return v
}