通道缓冲区如何工作? [重复]

This question already has an answer here:

I went through a series of definitions to figure out how the buffer works but I just don't get it. Here is an example below, I changed the value of the buffer but I have no clue about what it does. Can some one explain it to me based on this example and provide some test cases of how/why it's working? Thanks.

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
}
</div>

If a channel does not have a buffer then only a single item can be sent on it at a time. This means code that sends on it will block until some receiver reads the item out of the channel. Here's a contrived example; https://play.golang.org/p/HM8jdIFqsN 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("We block cause that channel is full")
   } }()

}

There's plenty of other things I could do to demonstrate the same but the basic idea is, if you pass a channel into some goroutine and the channel is not buffered, the goroutine which sends on the channel will block until the item it sent is received. With a buffered channel you can send as long as the buffer isn't at capacity. Basically, if you spin up goroutines which are doing work and returning the results and they're moving faster than the code that spawned them, you may want to use a buffered channel to open up that bottle neck.

EDIT: If it's still not obvious what's happening look at this; 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
   }
}