go并发模式之----阻塞/屏障模式

常见模式之一:阻塞/屏障模式

定义

顾名思义,就是阻塞等待所有goroutine,直到所有goroutine完成,聚合所有结果

使用场景

  • 多个网络请求,聚合结果

  • 大任务拆分成多个子任务,聚合结果

示例

package main
​
import (
  "fmt"
  "time"
)
​
func task1(n int, res chan int) {
  time.Sleep(time.Millisecond * 30)
  res <- n * n
}
​
func task2(n int, res chan int) {
  time.Sleep(time.Millisecond * 10)
  res <- n + n
}
​
func task3(n int, res chan int) {
  time.Sleep(time.Millisecond * 20)
  res <- n / n
}
​
func main() {
  res := make(chan int, 3)
  defer close(res)
  go task1(2, res)
  go task2(3, res)
  go task3(4, res)
  var resArr []int
  for i := 0; i < 3; i++ {
    resArr = append(resArr, <-res)
  }
  fmt.Println(resArr)
}

打印结果:

[6 1 4]

特殊使用

当我们并发请求,但是聚合结果时,需要顺序给出, 如上例,我们打印想要按照task1,task2,task3 依次给出

可以结合slice 和 和结果收集结构体 改写如下

package main
​
import (
  "fmt"
  "time"
)
​
func task1(n int, res chan ResultMap) {
  time.Sleep(time.Millisecond * 30)
  res <- ResultMap{
    Key: "task1", 
    Res: n * n,
  }
}
​
func task2(n int, res chan ResultMap) {
  time.Sleep(time.Millisecond * 10)
  res <- ResultMap{
    Key: "task2", 
    Res: n + n,
  }
}
​
func task3(n int, res chan ResultMap) {
  time.Sleep(time.Millisecond * 20)
  res <- ResultMap{
    Key: "task3", 
    Res: n / n,
  }
}
​
type ResultMap struct {
  Key string
  Res int
}
​
func main() {
  taskList := []string{"task1", "task2", "task3"}
  res := make(chan ResultMap, 3)
  defer close(res)
  go task1(2, res)
  go task2(3, res)
  go task3(4, res)
  var resArr []int
  l := len(taskList)
  collectMap := make(map[string]int)
  for i := 0; i < l; i++ {
    tmp := <-res
    collectMap[tmp.Key] = tmp.Res
  }
  for _, vv := range taskList {
    resArr = append(resArr, collectMap[vv])
  }
  fmt.Println(resArr)
}
​如果有更好的顺序收集结果方式,欢迎评论区指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值