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