go并发收集数据并统一存放到数组中


一个项目中遇到的问题,需要调用多个函数并对结果做统一返回,钻研了一下,代码如下


package main

import (
	"fmt"
	"sync"
	"time"
)

var wg sync.WaitGroup

func main() {
	// cmd.Execute()
	defer timeCost()()
	var res []string
	ch := make(chan []string, 2)
	done := make(chan bool)
	wg.Add(2)
	cal_f := []func() []string{demo1, demo2}
	for _, f := range cal_f {
		go cal(f, ch)
	}
	go collect(&res, ch, done)
	wg.Wait()   //此时主协程会阻塞,直到两个cal都执行完毕
	close(ch)   //关闭ch后,ch只读不写,当ch为空后,collect中的for循环执行完毕,进而执行done<-true
	<-done      //此时主协程会被阻塞,直到collect执行完毕
	close(done)
	fmt.Println(res)
}

func cal(f func() []string, ch chan []string) {
	defer wg.Done()
	ch <- f()
}

func collect(res *[]string, ch chan []string, done chan bool) {
	for data := range ch {
		*res = append(*res, data...)
	}
	done <- true
}

func timeCost() func() {
	start := time.Now()
	return func() {
		tc := time.Since(start)
		fmt.Printf("time cost = %v\n", tc)
	}
}

func demo1() []string {
	time.Sleep(500 * time.Millisecond)
	return []string{"hello", "hi"}
}

func demo2() []string {
	time.Sleep(600 * time.Millisecond)
	return []string{"milk", "john"}
}

运行结果如下

[hello hi milk john]
time cost = 600.454949ms

文章作者: Hiper
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Hiper !
  目录