Home  >  Article  >  Backend Development  >  How does buffered channel behavior differ from what I expect from Go?

How does buffered channel behavior differ from what I expect from Go?

PHPz
PHPzforward
2024-02-09 10:09:21333browse

缓冲通道的行为与我对 Go 的期望有何不同?

In the Go language, a buffered channel is a special type of channel that behaves differently from ordinary channels. When a normal channel sends data, the sender will be blocked until a receiver receives the data. Buffered channels allow the sender to continue sending data when the channel is not full without being blocked. This allows the sender to complete the sending operation faster without having to wait for the receiver. For Go language users, the behavior of buffered channels can provide higher concurrency performance and better response speed.

Question content

I'm trying to understand how buffered channels work and write a code snippet for it

package main

import (
    "fmt"
)

func squares(c chan int) {
    for i := 0; i < 4; i++ {
        num := <-c
        fmt.println(num * num)
    }
}

func main() {
    fmt.println("main() started")
    c := make(chan int, 3)
    
        go squares(c)

    c <- 1
    c <- 2
    c <- 3
    c <- 4 // blocks here

    fmt.println("main() stopped")
}

The way I expected the program to behave, the main goroutine starts and continues until c<-4, at which point it blocks and control goes to the square goroutine (because the buffer capacity is 3). The loop in the squares goroutine continues until the fourth iteration, when the channel is empty. Read operations on an empty channel block, so control is returned to the main goroutine. At this time, the write operation to the channel (c<-4) is executed, we print "main() has stopped", and the program ends.

means that the output I expect is,

main() started
1
4
9
main() stopped

But I got the output,

main() started
1
4
9
16
main() stopped
how? Am I missing something about how exactly channels work?

Solution

That’s not how channels work.

Goroutines run concurrently. This means that when a Goroutine sends to a buffered channel, another Goroutine waiting to receive from that channel can receive it immediately. It doesn't wait for the channel to fill up.

As for the end of the program, when you send the last number to the channel, there is no guarantee that the goroutine will pick it up and print the output before the program ends, because you are not waiting for the goroutine to complete. So, luckily, it runs and prints the output. There will be other executions where this will not happen and the program will terminate before the goroutine prints the output.

The above is the detailed content of How does buffered channel behavior differ from what I expect from Go?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete