Today I learned about Go's Producer and Consumer, so I will output about it.
--Basic grammar of Go --Channel
I think this article will be easier to understand if you have this knowledge. If you don't understand, I also wrote an article about channels and Goroutine, so please refer to it if you like! [Golang] About Go language channel [Golang] Go Language Basics What is Goroutine?
First of all, please see the figure below.
The flow is that the processing result of parallel processing (Producer) run from func main is sent to the channel, and the sent value is processed by Consumer. Specifically, it seems to be used by going to various servers, analyzing the log, sending the result on the channel (Producer), receiving the value of the sent channel on the Consumer, and processing it!
You can't understand it from words alone, so let's actually write the code.
package main
import (
"fmt"
"sync"
)
func producer(ch chan int, i int) {
//Some processing
ch <- i * 2
}
func consumer(ch chan int, wg *sync.WaitGroup) {
for i := range ch {
fmt.Println("process", i*100)
wg.Done()
}
}
func main() {
var wg sync.WaitGroup
ch := make(chan int)
//Producer
for i := 0; i < 10; i++ {
wg.Add(1)
go producer(ch, i)
}
//Consumer
go consumer(ch, &wg)
wg.Wait()
close(ch)
}
**Execution result**
process 0
process 400
process 200
process 600
process 800
process 1000
process 1200
process 1400
process 1600
process 1800
First, create a wg variable and a channel and store them in the ch variable. Now generate ** Producer **. The number of parallel processes is incremented by setting wg.Add (1). (I'm telling wg that there are 10 concurrencies because I'm looping 10 times here) Then, pass ch and i as arguments to the ** producer function ** and attach a go statement to run parallel processing.
The ** producer function ** does some processing and sends the ** i * 2 ** to the channel. Then, when the processing is finished, pass the addresses of ch and wg to the ** consumer function **. The ** consumer function ** takes out the channel value sent from the ** producer function ** and loops it with the range. The content of the loop processing outputs i * 1000, and wg.Done tells that this processing is finished. This is repeated 10 times.
When this is done, go to wg.Wait (here, wait until the process is completed 10 times) ** close (ch) to describe that the channel is closed. ** **
As a caveat here, ** consumer itself is Goroutine, so even after 10 times of processing, it is still trying to get the value from the channel, waiting for the channel to be sent from the producer function to turn the range. I will. ** ** You can see that the producer function sends 10 values to the channel, but the consumer function doesn't know that 10 values are sent. It will try to loop through the next value unless it signals the end of the channel. How sane! .. Therefore, it is necessary to describe that the channel is closed with "I will not send the value from the producer function anymore" as close (ch)!
I hope this article helps you to understand it! We would appreciate it if you could comment on your impressions and suggestions!
Recommended Posts