关于golang:Golang协程之了解管道的缓存能力

50次阅读

共计 1878 个字符,预计需要花费 5 分钟才能阅读完成。

作者:ReganYue

起源:恒生 LIGHT 云社区

Golang 协程之理解管道的缓存能力

大家好,这里是致力变得优良的 R 君,这次咱们持续来进行 Golang 系列《让咱们一起 Golang》,区块链系列内容明年会持续更新,共识算法曾经根本结束,如果不出意外,除夕那个星期就是介绍如何构建公链我的项目了,本次咱们来理解管道的缓存能力,这是一个比拟容易了解的知识点,咱们来看一看吧!

咱们之前讲过,当应用 make 建设管道时,第二个参数为零,就证实这个管道是无缓存能力的管道。只有没人写就永远读不进去,只有没人读就永远写不进去。例如:

ch := make(chan int,0)

管道的缓冲区能被初始化为指定的缓冲区容量。如果为零,或者省略了大小,则该通道是无缓冲的。

如果将第二个参数改为 8(这里能够为任意大小),这就阐明缓存能力为 8,即便不读,也能写入 8 个元素。

package main

import (
    "fmt"
    "time"
)

func main() {
    //The channel's buffer is initialized with the specified buffer capacity.
    //If zero, or the size is omitted, the channel is unbuffered.
    ch := make(chan int,0)

    go func() {
        ch <- 123
        fmt.Println("数据已写入")
    }()

    go func() {time.Sleep(2*time.Second)
        x:= <- ch
        fmt.Println("数据已读出",x)
    }()

    time.Sleep(5*time.Second)
    fmt.Println("Game Over!")
}

这段代码在运行过程中,因为一条协程在写入管道缓冲区,另一条协程在读取管道的缓冲区,然而读取管道缓冲区的那条协程会 sleep 两秒,所以在前两秒另一条写入管道缓冲区的协程也不能写入。

如果让写入管道缓冲区的那条协程 sleep 两秒,那么前两秒另一条读取管道缓冲区的协程也不能读取数据。

如果一个缓冲区大小为 3 的管道,写入 4 个值,那么第 4 个值就写入不了,运行后果是这样的:

 写入 1
写入 2
写入 3 

上面咱们来看一看管道内的元素个数及它的缓存能力吧:

package main

import (
    "fmt"
    "time"
)

func main101() {ch := make(chan int,3)

    go func() {
        ch <- 1
        fmt.Println("写入 1")
        ch <- 2
        fmt.Println("写入 2")
        ch <- 3
        fmt.Println("写入 3")
        // 管道的缓冲区曾经存满,不能再写入!ch <- 4
        fmt.Println("写入 4")
    }()
    time.Sleep(5 * time.Second)
}

func main() {ch := make(chan int,3)
    fmt.Println("元素的个数为",len(ch),"缓存能力为",cap(ch));

    ch <- 123
    fmt.Println("元素的个数为",len(ch),"缓存能力为",cap(ch));
    ch <- 123
    fmt.Println("元素的个数为",len(ch),"缓存能力为",cap(ch));
    ch <- 123
    fmt.Println("元素的个数为",len(ch),"缓存能力为",cap(ch));
    
}

运行后果是

 元素的个数为 0 缓存能力为 3
元素的个数为 1 缓存能力为 3
元素的个数为 2 缓存能力为 3
元素的个数为 3 缓存能力为 3
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan send]:
main.main()
    E:/main.go:36 +0x4e5

Process finished with exit code 2

咱们能够看到管道的缓存能力是没有变动的,然而存入的元素个数是在变动的。

咱们能够看到这里呈现了死锁,这里主协程永远无奈继续执行。

咱们再来理解一下管道的无关常识。

据理解,管道是建设在堆下面的。应用 make 函数返回的是指针,这就是为什么咱们可能在函数之间传递管道,不须要传递指向管道的指针。

ch := make(chan int,0)

应用 make 创立一个管道只能传输同一类型的数据,建设一个管道时须要指定一个数据类型,不容许通过一个管道传输多种类型的数据。


想向技术大佬们多多取经?开发中遇到的问题何处探讨?如何获取金融科技海量资源?

恒生 LIGHT 云社区,由恒生电子搭建的金融科技业余社区平台,分享实用技术干货、资源数据、金融科技行业趋势,拥抱所有金融开发者。

扫描下方小程序二维码,退出咱们!

正文完
 0