Golang high concurrency: producer consumer model
In this blog post, we mainly introduce the producer consumer model through several examples.
Case 1
Let's look at the producer process in the first example.
//Producer collaboration go func() { for { product := strconv.Itoa(time.Now().Nanosecond()) chanShop <- "commodity" + product fmt.Println("Produced goods",product) time.Sleep(1000 * time.Millisecond) } }()
Producer collaboration is a continuous production process, which converts time into a string, and then continuously produces a product string. Strconv Itoa() converts an integer to a string type. time.Now() is the current time, while Nanosecond() converts it to nanoseconds. Then put the obtained product serial number string into the video pipeline, then output what product has been produced, then sleep for one second, and then produce.
As for the consumer association process, I believe you have guessed what it is. Let's have a look.
//Consumer collaboration go func() { for{ product := <-chanShop fmt.Println("Consumer products",product) time.Sleep(time.Second) } }()
Take a product from the commodity pipeline each time, then output what products are consumed, then sleep for one second, and then continue to consume.
Let's take a look at the main process of this case
//Main coordination process for { time.Sleep(time.Second) }
The result is
Product 607861100 consumed Produced goods 607861100 Produced goods 607929500 Products consumed 607929500 Produced goods 608013000 Consumption of product goods 608013000 Produced goods 608018400 Consumption of product goods 608018400
Yes, a steady stream of production and consumption, production and consumption.
Case 2
Let's take a look at the second case. In this case, we introduced the concept of "logistics".
Let me show you the main function first:
func main() { chanStorage := make(chan string ,100) chanShop := make(chan string, 100) go producer(chanStorage) go logistics(chanStorage,chanShop) go consumer(chanShop) for { time.Sleep(time.Second) } }
It is mainly to establish two pipelines of stores and logistics, and then establish three cooperation processes of producers, consumers and logistics. Then, the main cooperation process has not been go die.
Then let's take a look at the producer process
func producer(chanStorage chan string) { for i:=0;i<10;i++{ product := strconv.Itoa(time.Now().Nanosecond()) chanStorage <- "product"+product fmt.Println("Produced products",product) time.Sleep(time.Second) } close(chanStorage) }
It is the same as the first case, but we only produced 10 products and put them into the warehouse, and then closed the warehouse.
Then look at what the logistics collaboration process has done:
func logistics(chanStroge,chanShop chan string) { for p:= range chanStroge{ fmt.Println("Logistics complete transshipment",p) chanShop <- p } fmt.Println("Goods transshipment completed!") }
Constantly scan the warehouse, take out the goods, and then transfer the goods to the store. When the producer closes the warehouse, the logistics also stops transshipment.
Consumers are constantly consuming, and then look at consumers:
func consumer(chanShop chan string) { for{ product := <-chanShop fmt.Println("Consumer products",product) } }
Wait for a commodity and sell it.
Then look at the running results
Production of products 605763200 logistics completed transshipment products 605763200 consumption of products 605763200 production of products 605826700 logistics completed transshipment products 605826700 consumption of products 605826700 production of products 619889800 logistics completed transshipment products 619889800 consumption of products 619889800 production of products 619906200 logistics completed transshipment products 619906200 consumption of products Product 619906200 produced product 627948700 logistics completed transshipment product 627948700 consumed product 627948700
We can see that production, transshipment and consumption are almost simultaneous.
Because when the logistics company stops transporting materials, the stores will also be closed, so we add:
close(chanShop) fmt.Println("Goods transshipment completed! The shop is closed!")
Then continue to replace the consumer's for loop with
for product := range chanShop{ //product := <-chanShop fmt.Println("product consumed" fmt.Println() } fmt.Println("consumption completed!")
You can only read the goods in the pipeline.