[Golang] About Go language Producer and Consumer

Today I learned about Go's Producer and Consumer, so I will output about it.

Prerequisite knowledge

--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?

What are Producer and Consumer?

First of all, please see the figure below. スクリーンショット 2020-09-30 223000.png

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)!

Thank you for reading to the end!

I hope this article helps you to understand it! We would appreciate it if you could comment on your impressions and suggestions!

Recommended Posts

[Golang] About Go language Producer and Consumer
[Golang] Basics of Go language About value receiver and pointer receiver
About _ and __
[Golang] Go language basics What is Goroutine?
About Go functions
About Go Interface
Go language to see and remember Part 7 C language in GO language
Learn about Go slices
Go language learning record
Go language environment construction
Golang error and panic
About Go control syntax
Go language cheat sheet
Features of Go language
About Go Modules (vgo)
About cross-validation and F-number
[Go language] Collect and save Vtuber images using Twitter API
Go language to see and remember Part 8 Call GO language from Python