多路复用channel的时候,如何优雅的关闭通道

IamSimple · · 1766 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

      最近在学习Go语言,学了有一个月时间,从微信公众号“码洞”上看到了快学系列教材,很棒的文章。最新的一篇是讲通道,里面提到了多路复用channel,但是没有讲在多路复用中,如何优雅的关闭通道,我在这里做了一些尝试,发出来供交流。

《快学 Go 语言》第 12 课 —— 神秘的地下通道 的访问地址如下,先阅读:
https://mp.weixin.qq.com/s/eZTFa-8drmkZUXsvHycorQ

然后下面是我增加通道关闭后的代码,详见注释:

package main

import (
    "fmt"
    "time"
)

func send(ch chan int, gap time.Duration) {
    //每个通道模拟发送5个消息就结束
    for i := 0;i<5;i++{
        //i++
        ch <- i
        time.Sleep(gap)
    }
    //关闭通道
    close(ch)
}

func recv(ch1 chan int, ch2 chan int) {
    //定义临时变量,记录通道状况,一旦关闭就标记
    b1,b2:=true,true
    for i := 0;;i++{
        if(b1==false && b2==false ){
            //如果多个通道都关闭了,退出
            return
        }
        select {
            case v, ok := <- ch1:
                //fmt.Printf("recv %d from ch1\n", v)
                if (ok){
                    fmt.Printf("%d :recv %d from ch1 %v \n", i,v,ok)
                } else {
                    //标记ch1关闭
                    b1 = ok
                }
                
            case v, ok := <- ch2:
                //fmt.Printf("recv %d from ch2\n", v)
                if (ok){
                    fmt.Printf("%d :recv %d from ch2 %v \n", i,v,ok)
                } else {
                    //标记ch2关闭
                    b2 = ok
                }
        }
    }
}

func main() {
    var ch1 = make(chan int)
    var ch2 = make(chan int)
    //启动ch1通道
    go send(ch1, time.Second)
    //启动ch2通道
    go send(ch2, 2 * time.Second)
    recv(ch1, ch2)
}

 


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1766 次点击  
加入收藏 微博
2 回复  |  直到 2018-12-06 11:21:29
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传