Detailed explanation of grpool goroutine pool | Coroutine management

Continue to create, accelerate growth! This is the 9th day of my participation in the "Nuggets Daily New Plan · June Update Challenge", click to view the details of the event

foreword

The goroutine coroutine is very lightweight, which is why go supports high concurrency, but the frequent creation and destruction of goroutines puts a lot of pressure on the GC.

The role of grpool is to reuse goroutines to reduce the performance consumption of frequent creation and destruction.

noun concept

Pool: goroutine pool, used to manage several reusable goroutine coroutine resources

Worker: The goroutine participating in task execution in the pool object. A worker can execute several jobs until there are no more waiting jobs in the queue.

Job: The task added to the task queue of the pool object waiting to be executed is a func() method. A job can only be acquired and executed by one worker at the same time.

Example of use

Use the default coroutine pool to limit 100 coroutines to execute 1000 tasks

pool.Size() Get the number of coroutines currently working

pool.Jobs() Get the number of pending jobs in the current pool

package main

import (
   "fmt"
   "github.com/gogf/gf/os/grpool"
   "github.com/gogf/gf/os/gtimer"
   "sync"
   "time"
)

func main() {
   pool := grpool.New(100)

   //添加1千个任务
   for i := 0; i < 1000; i++ {
      _ = pool.Add(job)
   }

   fmt.Println("worker:", pool.Size()) //当前工作的协程数量
   fmt.Println("jobs:", pool.Jobs())   //当前池中待处理的任务数量

   gtimer.SetInterval(time.Second, func() {
      fmt.Println("worker:", pool.Size()) //当前工作的协程数
      fmt.Println("jobs:", pool.Jobs())   //当前池中待处理的任务数
   })

   //阻止进程结束
   select {}
}

//任务方法
func job() {
   time.Sleep(time.Second)
}
复制代码

print result

image.png

Isn't it so simple~

A trip to the pit

A simple scenario, please use coroutine to print 0~9.

common mistakes

Let's see if there is any problem with the code below, please predict the printing result.

wg := sync.WaitGroup{}
for i := 0; i < 9; i++ {
   wg.Add(1)
   go func() {
      fmt.Println(i)
      wg.Done()
   }()
}
wg.Wait()
复制代码

Don't worry about the answer

.

.

.

Guess what the print result is

print result

image.png

Analyze the reasons

For asynchronous threads/coroutines, when the function is registered for asynchronous execution, the function does not actually start executing (only the memory address goroutineof the variable is saved in the stack during registration i), and the function will read it once it starts executing. The value of the variable i, and this time ithe value of the variable has been incremented 9.

Correct spelling

wg := sync.WaitGroup{}
for i := 0; i < 9; i++ {
   wg.Add(1)
   go func(v int) {
      fmt.Println(v)
      wg.Done()
   }(i)
}
wg.Wait()
复制代码

print result

image.png

use grpool

Using grpool is the same as using go, you need to assign the value of the current variable i to a temporary variable that will not change, and use the temporary variable in the function instead of using the variable directly i.

error code

wg := sync.WaitGroup{}
for i := 0; i < 9; i++ {
   wg.Add(1)
   _ = grpool.Add(func() {
      fmt.Println(i) //打印结果都是9
      wg.Done()
   })
}
wg.Wait()
复制代码

print result

image.png

correct code

wg := sync.WaitGroup{}
for i := 0; i < 9; i++ {
   wg.Add(1)
   v := i //grpoll.add() 的参数只能是不带参数的匿名函数 因此只能以设置临时变量的方式赋值
   _ = grpool.Add(func() {
      fmt.Println(v)
      wg.Done()
   })
}
wg.Wait()
复制代码

print result

image.png

Summarize

Through this article, we learned that the role of grpool is to reuse goroutines to reduce the performance consumption of frequent creation and destruction.

I also learned about the mistakes that are easy to make when using coroutines, and how to solve problems with temporary variables.

A digression: the basic concepts of grpool: Pool, Worke, Job are exactly the same as the order dispatching system I designed before.

at last

Thank you for reading, and welcome everyone: like, favorite,coin(focus on)! ! !

8e95dac1fd0b2b1ff51c08757667c47a.gif

Guess you like

Origin juejin.im/post/7104661248213516319