美文网首页
Go语言带缓冲的通道

Go语言带缓冲的通道

作者: 码二哥 | 来源:发表于2020-02-14 17:40 被阅读0次

    参考:
    http://c.biancheng.net/view/100.html

    关键点

    通过关键词汇,实现快速理解,记忆目的

    1、缓存通道和无缓存通道的主要区别?

    缓存通道,要求数据发送接收必须同时完成

    缓存通道,数据的发送和接收不是必须同时完成的

    2、缓存通道 存在 阻塞情况

    通道被填满时,如果发送数据,协程阻塞,也就是协程等待着

    通道里没有数据时,一直接收数据,协程也会阻塞,协程开始等待

    3、为什么Go语言对通道限制长度而提供无限长度的通道?

    防止数据发送方一直发送数据,内存不断增加,可能导致应用程序奔溃

    1、创建带缓冲通道

    如何创建带缓冲的通道呢? 参见如下代码:

    通道实例 := make(chan 通道类型, 缓冲大小)
    
    • 通道类型:和无缓冲通道用法一致,影响通道发送和接收的数据类型。

    • 缓冲大小:决定通道最多可以保存的元素数量。

    • 通道实例:被创建出的通道实例。

    下面通过一个例子中来理解带缓冲通道的用法,参见下面的代码:

    package main
    import "fmt"
    func main() {
        // 创建一个3个元素缓冲大小的整型通道
        ch := make(chan int, 3)
        // 查看当前通道的大小
        fmt.Println(len(ch))
        // 发送3个整型元素到通道
        ch <- 1
        ch <- 2
        ch <- 3
        // 查看当前通道的大小
        fmt.Println(len(ch))
    }
    

    代码输出如下:

    0
    3
    

    代码说明如下:

    • 第 8 行,创建一个带有 3 个元素缓冲大小的整型类型的通道。

    • 第 11 行,查看当前通道的大小。带缓冲的通道在创建完成时,内部的元素是空的,因此使用 len() 获取到的返回值为 0。

    • 第 14~16 行,发送 3 个整型元素到通道。因为使用了缓冲通道。即便没有 goroutine 接收,发送者也不会发生阻塞。

    • 第 19 行,由于填充了 3 个通道,此时的通道长度变为 3。

    2、阻塞条件

    缓冲通道在很多特性上和无缓冲通道是类似的。

    缓冲通道可以看作是长度永远为 0带缓冲通道。

    因此根据这个特性,缓冲通道在下面列举的情况下依然会发生阻塞

    • 带缓冲通道被填满时,尝试再次发送数据时发生阻塞

    • 带缓冲通道为空时,尝试接收数据时发生阻塞

    2.1、为什么Go语言对通道要限制长度提供无限长度的通道?

    我们知道通道(channel)是在goroutine 间通信的桥梁

    使用 goroutine 的代码必然有一方提供数据,一方消费数据。

    提供数据一方的数据供给速度大于消费方的数据处理速度时,

    如果通道不限制长度,那么内存将不断膨胀直到应用崩溃

    因此,限制通道的长度有利于约束数据提供方的供给速度,

    供给数据量必须在消费方处理量+通道长度的范围内,

    才能正常地处理数据。

    相关文章

      网友评论

          本文标题:Go语言带缓冲的通道

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