通道缓冲区如何工作?

时间:2015-04-22 21:00:42

标签: go

我经历了一系列定义来弄清楚缓冲区是如何工作的,但我还是没有得到它。下面是一个例子,我改变了缓冲区的值,但我不知道它的作用。有人可以根据这个例子向我解释并提供一些测试用例,说明它是如何工作的?感谢。

package main

import (
    "fmt"
    "time"
)

func send(out, finish chan bool) {
    for i := 0; i < 5; i++ {
        out <- true
        time.Sleep(1 * time.Second)
        fmt.Println("Fin d'une écriture")
    }
    finish <- true
    close(out)
}
func recv(in, finish chan bool) {
    for _ = range in {
        fmt.Println("Fin d'une lecture")
        time.Sleep(10 * time.Second)
    }
    finish <- true
}
func main() {
    chanFoo := make(chan bool, 3)
    chanfinish := make(chan bool)
    go send(chanFoo, chanfinish)
    go recv(chanFoo, chanfinish)
    <-chanfinish
    <-chanfinish
}

1 个答案:

答案 0 :(得分:2)

如果某个频道没有缓冲区,则一次只能在其上发送一个项目。这意味着在其上发送的代码将阻塞,直到某个接收器从通道中读取该项目。这是一个人为的例子; https://play.golang.org/p/HM8jdIFqsN     包主要

import (
    "fmt"
)


func main() {
   blocker := make(chan bool)
   nonBlocker := make(chan bool, 5)

   for i := 0; i < 5; i++ {
        nonBlocker <- true
        fmt.Println("We keep going")
   }

   go func () {

    for i := 0; i < 5; i++ {
        blocker <- true
        fmt.Println("We block cause that channel is full")
   } }()

}

我还可以做很多其他的事情来证明这一点,但基本的想法是,如果你将一个频道传递到某个goroutine并且频道没有被缓冲,那么在频道上发送的goroutine将会阻塞直到它发送的项目收到了。使用缓冲通道,只要缓冲区没有容量就可以发送。基本上,如果你旋转正在工作并返回结果的goroutine并且它们比产生它们的代码移动得更快,你可能想要使用缓冲通道打开那个瓶颈。

编辑:如果仍然不明显发生了什么,请看这个; https://play.golang.org/p/9SXc4M1to4

package main

import (
    "fmt"
)


func main() {
   blocker := make(chan bool)
   nonBlocker := make(chan bool, 5)

   for i := 0; i < 5; i++ {
        nonBlocker <- true
        fmt.Println("We keep going")
   }

   go func () {

    for i := 0; i < 5; i++ {
        blocker <- true
        fmt.Println("Now we see this cause the reciever keeps opening the channel up again!")
   } }()

   for i := 0; i < 5; i++ {
      <-blocker
   }
}