Golang high concurrency: producer consumer model

Posted by yellowzm on Sun, 19 Dec 2021 09:38:49 +0100

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.

Topics: Go Concurrent Programming