php editor Youzi will answer a common question in this article: "Why does the buffer of Go Channel not limit writing/reading correctly?" In the Go language, Channel It is a mechanism for communication between coroutines. When we use a Channel with a buffer, we expect to be able to control the behavior of the program by limiting the number of write or read operations. However, in fact, the Channel buffer cannot directly limit the number of write/read operations. The causes and solutions to this problem will be elaborated below.
I am trying to communicate between two go routines using channels. First, I created the integer channel and then passed it as a parameter to a go routine that prints a sequence of numbers from 0 to 10. The output of these programs makes no sense.
This is the main code:
func worker(identifier string, ch chan<- int) { fmt.printf("entering worker %s\n", identifier) for i := 0; i < 10; i++ { fmt.printf("writing %d\n", i) ch <- i } fmt.printf("exiting worker %s\n", identifier) close(ch) } func main() { ch := make(chan int) go worker("1", ch) for v := range ch { fmt.printf("reading %d\n", v) } }
For this code execution, I got the following output:
entering worker 1 writing 0 writing 1 reading 0 reading 1 writing 2 writing 3 reading 2 reading 3 writing 4 writing 5 reading 4 reading 5 writing 6 writing 7 reading 6 reading 7 writing 8 writing 9 reading 8 reading 9 exiting worker 1
Note that there are two write executions followed by two read executions.
Later, I set a buffer size to achieve the following functions:
func main() { ch := make(chan int, 3) // <= buffer go worker("1", ch) for v := range ch { fmt.printf("reading %d\n", v) } }
Then, we get the following output:
Entering worker 1 Writing 0 Writing 1 Writing 2 Writing 3 Writing 4 Reading 0 Reading 1 Reading 2 Reading 3 Reading 4 Writing 5 Writing 6 Writing 7 Writing 8 Writing 9 Reading 5 Reading 6 Reading 7 Reading 8 Reading 9 Exiting worker 1
Note that now we have 5 write executions and then 5 read executions.
Once we have the code and output, the final question arises: why do these executions behave the way they do? First, isn't it supposed to only read and write one number at a time? Beyond that, why does the second execution read and write 5 numbers each time instead of 3 (since that's the buffer size)?
You are confused when a message is printed and when a number is read from or written to the channel.
When a write occurs, the "write" message does not occur. They occur at some point between writes. Likewise, the "reading" message occurs at some point between reads.
Here is one way to arrange the first code snippet, which produces the output shown:
Control is continuously passed between main and Worker like this, each printing 2 messages before blocking.
Likewise, your second fragment can be arranged like this:
The above is the detailed content of Why doesn't Go Channel's buffer limit writes/reads correctly?. For more information, please follow other related articles on the PHP Chinese website!