SoFunction
Updated on 2025-03-04

Detailed explanation of the difference between whether the golang channel has a buffer

The difference between buffering or not

Image explain the difference between unbuffered and buffered:

Unbuffered is synchronous. For example, make(chan int), which means a sender goes to your doorstep to deliver the letter. If you are not at home, he will not leave. You must receive the letter before he will leave. The unbuffered letter is guaranteed to be in your hands.

Buffering is asynchronous. For example, make(chan int, 1), which means that a sender goes to your mailbox and still goes to your house. He turns around and leaves. Unless your mailbox is full, he must wait for the mailbox to be empty. The buffered mailbox can enter your mailbox.

channel No buffering

Example 1:

func main() {
    ch := make(chan int)
    ch <- 1 // An error has been reported, because ch has no buffering, and if one is saved, you must get it out immediately    (<- ch)
}

correct:

func main() {
    ch := make(chan int)
    go tt(ch) // Open a goroutine    ("I will execute 1111 first")
    (<-ch) // Because there is a goroutine in front, this line is executed first than go tt(ch), which is blocked here. After the statement in tt(ch) is executed, this line will execute it    // I will execute 1111 first    // I will execute 2222 first    // 1
}
 
func tt(ch chan int) {
    ("I will execute 2222 first")
    ch <- 1
}

Example 2:

package main
 
import "fmt"
 
func main() {
    ch := make(chan int) // Unbuffered channel    go unbufferChan(ch)
 
    for i := 0; i < 10; i++ {
        ("receive ", <-ch) // Read out the value    }
}
 
func unbufferChan(ch chan int) {
    for i := 0; i < 10; i++ {
        ("send ", i)
        ch <- i // Write value    }
}
 
// Output// send  0
// send  1
// receive  0
// receive  1
// send  2
// send  3
// receive  2
// receive  3
// send  4
// send  5
// receive  4
// receive  5
// send  6
// send  7
// receive  6
// receive  7
// send  8
// send  9
// receive  8
// receive  9

channel with cache

Example 1:

The speed of putting it in is faster. First, fill it up 5 pieces, blocking it; the speed of putting it in is slow. After putting it in 5 pieces, you can start to fetch it. Since the buffer is full, you can only put it in again after taking out one. After putting it out, although the buffer is closed, the contents of the buffer are still retained, so you can continue to fetch it out.

func put(c chan int) {
    for i := 0; i < 10; i++ {
       c <- i
       (100 * )
       ("->Put in", i)
    }
    ("=All were put in!Close the buffer,But the data inside will not be lost,Can still be taken out。")
    close(c)
}
 
func main() {
    ch := make(chan int, 5)
    go put(ch)
    for {
       (1000 * )
       data, ok := <-ch
       if ok == true {
          ("<-Take it out", data)
       } else {
          break
       }
    }
}
 
// ->Put in 0// ->Put in 1// ->Put in 2// ->Put in 3// ->Put in 4// <-Removal 0// ->Put in 5// <-Removal 1// ->Put in 6// <-Removal 2// ->Put in 7// <-Removal 3// ->Put in 8// <-Removal 4// ->Put in 9// =Everything is put in!  Close the buffer, but the data inside will not be lost and can be retrieved.// <-Removal 5// <-Removal 6// <-Removal 7// <-Removal 8// &lt;-take out 9

Example 2: Save and get

package main
 
import"fmt"
 
var c = make(chan int, 5)
 
func main() {
    go worker(1)
    for i := 1; i &lt; 10; i++ {
       c &lt;- i
       (i)
       ("cap = ", cap(c), " len = ", len(c))
    }
}
 
func worker(id int) {
    for {
       _ = &lt;-c
    }
}
 
// Run output:// 1
// cap =  5  len =  0
// 2
// cap =  5  len =  0
// 3
// cap =  5  len =  1
// 4
// cap =  5  len =  2
// 5
// cap =  5  len =  0
// 6
// cap =  5  len =  1
// 7
// cap =  5  len =  2
// 8
// cap =  5  len =  2
// 9
// cap =  5  len =  0

This is the end of this article about the details of whether the golang channel has a buffer or not. For more related golang channel buffer content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!