Zhong__Go程使用channel接收数据

时间:2021.11.15

环境:Windows

目的:go程及多go程使用channel接收数据

说明:

作者:Zhong QQ交流群:121160124 欢迎加入!

在go语言开发中 使用go程可以很方便的实现并发的效果 以提升效率

有时候需要收集go程的结果 那么可以使用channel

一般我们可以这样  使用  go程 + channel + sync.WaitGroup  实现  并发、等待go程完成和收集结果

package main

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

func main() {
   var wg sync.WaitGroup
   ch := make(chan interface{})

   for i := 0; i < 5; i++ {
      wg.Add(1)
      i := i
      go func() {
         defer wg.Done()
         ch <- []interface{}{i}  // i不会重复
      }()
   }

   go func() {
      defer close(ch)
      wg.Wait()
   }()

   time.Sleep(time.Second)
   for msg := range ch {
      fmt.Println(msg)  // 数据全面
   }
}

上面是一种常见的实现方法 使用了一个go程来等待wg的完成和关闭channel 相对于网上很多的demo做了优化(网上很多的例子都是不负责的 随意给个demo看似拿来就能用 但往往产生的结果并并不是期望的那样) 

那接下来继续深入一下 上面是基础的一个for循环来生成多个go程并发的执行 但如果是多层循环是如何优雅并全面收集结果的呢?其实这种需求在生产中很多很常见 网上大多没有提及或者代码存在bug(不是期望的结果) 

使用以下方法可以优雅的做到

package main

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

var ch chan interface{}
var wg sync.WaitGroup

func main() {
   //1. 外层循环
   for j := 0; j < 5; j++ {
      ch = make(chan interface{}, 2)
      //2. 内层循环
      for i := 0; i < 5; i++ {
         wg.Add(1)
         i := i
         go func() {
            defer wg.Done()
            ch <- []interface{}{i} // i不会重复
         }()
      }

      //3. 不能放在for循环之上 否则go func()与for循环之间若有耗时很可能提前close ch
      go func() {
         defer close(ch)
         wg.Wait()
      }()
      time.Sleep(time.Second)

      //4.读取一次外层循环的ch数据
      for msg := range ch {
         fmt.Printf("%v", msg) // 数据全面
      }
      fmt.Println()
   }
}

上面的举例是比较常见的经典用法  下面这篇文章列举了更多使用方法:

Golang并发协程/Channel控制icon-default.png?t=M276https://blog.youkuaiyun.com/anyedianxia/article/details/123394357

主要详述了channel特性、关闭原则以及如下场景的举例:

1个发送者 1个接收者

1个发送者 n个接收者

n个发送者 1个接收者

n个发送者 n个接收者

关注微信公众号  加入qq聊天群: 121160124

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我变了_我没变

随意 。。。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值