美文网首页
go语言channle使用总结

go语言channle使用总结

作者: xyt001 | 来源:发表于2019-02-04 11:45 被阅读0次

    前言:

    channel 提供了一种通信机制,通过它,一个 goroutine 可以想另一 goroutine 发送消息。channel 本身还需关联了一个类型,也就是 channel 可以发送数据的类型。例如: 发送 int 类型消息的 channel 写作 chan int 。channel 很强大,但是还是有点坑,下面是我个人的总结。

    1.使用两个值接收 channel:

    <- channel 能够返回一个值或者 两个值,当返回两个值的时候 ,第二个是一个bool 变量,如果为 false ,就说明这个 channel 被关闭了。被关闭了的 channel ,会不断的 返回 该 channle 类型的 零值 和false,应该在代码 层面做好预防。

    unc main () {
        can := make(chan int ,8)
        can <- 1
        can <- 1
        can <- 1
    
        close(can)
        for {
            select {
            case tem := <- can:
                fmt.Println(tem)
                time.Sleep(time.Second)
            }
        }
    }
    

    就比如 这段代码,当can 被读取完管道里面的数据同时是关闭状态的时候,并不会像我们预期的想法那样阻塞住,反而不断的 返回零值。。

    func main () {
        can := make(chan int ,8)
        can <- 1
        can <- 1
        can <- 1
    
        close(can)
        for {
            select {
            case tem ,fla:= <- can:
                if fla == false {
                    //can = nil 如果这样的 select 就不会一直返回了,
                    // select 的 一个 nil的 channle就会阻塞住
                    return
                } else {
                    fmt.Println(tem)
                }
                time.Sleep(time.Second)
            }
        }
    }
    

    改成 这样我们就能完美 解决该问题了。

    2.使用for range 代替 select:

    select 能够同时监听 多个channle的 返回值,但是很多时候我们只是一个协程 监听一个 channle,这个时候我们不如 用for range。

    func main () {
        can := make(chan int ,8)
        can <- 1
        can <- 1
        can <- 1
    
        close(can)
    /*  for {
            select {
            case tem ,fla:= <- can:
                if fla == false {
                    //can = nil 如果这样的 select 就不会一直返回了,
                    //select 的 一个 nil的 channle就会阻塞住
                    return
                } else {
                    fmt.Println(tem)
                }
                time.Sleep(time.Second)
            }
        }
    */
        for i := range can {
            fmt.Println(i)
        }
    }
    

    当 for range 一个 channle ,如果 该 channle没有被关闭,会一直阻塞,如果 关闭了,会自动退出循环,很方便。代码简洁了很多!

    3.channle不仅仅是队列:

    channle 分为有缓存 和无缓存类型。

    1. 有缓存 channle 是一个消费队列。
    2. 无缓冲的channle 也可以当用。
    3. channle 因为能够 缓冲数据,所以还很适合 当连接池来用。

    具体怎么实现,大家自己可以网上找找资料。

    总结:

    以上就是我对channle的认识了,有啥不对的,欢迎留言

    相关文章

      网友评论

          本文标题:go语言channle使用总结

          本文链接:https://www.haomeiwen.com/subject/ladpsqtx.html