Continue a criar, acelere o crescimento! Este é o 9º dia da minha participação no "Nuggets Daily New Plan · June Update Challenge", clique para ver os detalhes do evento
prefácio
A corrotina de goroutine é muito leve, e é por isso que go suporta alta simultaneidade, mas a frequente criação e destruição de goroutines coloca muita pressão no GC.
O papel do grpool é reutilizar goroutines para reduzir o consumo de desempenho de criação e destruição frequentes.
conceito de substantivo
Pool: pool de goroutine, usado para gerenciar vários recursos de corrotina de goroutine reutilizáveis
Worker: A goroutine que participa da execução de tarefas no objeto pool. Um trabalhador pode executar vários trabalhos até que não haja mais trabalhos em espera na fila.
Job: A tarefa adicionada à fila de tarefas do objeto pool esperando para ser executada é um método func().Um job só pode ser adquirido e executado por um trabalhador ao mesmo tempo.
Exemplo de uso
Use o pool de corrotinas padrão para limitar 100 corrotinas para executar 1.000 tarefas
pool.Size() Obtém o número de corrotinas trabalhando atualmente
pool.Jobs() Obtém o número de trabalhos pendentes no pool atual
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)
}
复制代码
imprimir resultado
Não é tão simples~
Uma viagem ao poço
Um cenário simples, use corrotina para imprimir 0~9.
erros comuns
Vamos ver se há algum problema com o código abaixo, por favor, preveja o resultado da impressão.
wg := sync.WaitGroup{}
for i := 0; i < 9; i++ {
wg.Add(1)
go func() {
fmt.Println(i)
wg.Done()
}()
}
wg.Wait()
复制代码
Não se preocupe com a resposta
.
.
.
Adivinhe qual é o resultado da impressão
imprimir resultado
Analise os motivos
Para threads/corrotinas assíncronas, quando a função é registrada para execução assíncrona, a função não inicia a execução (somente o endereço goroutine
de memória da variável é salvo na pilha durante o registro i
), e a função o lerá assim que iniciar a execução. O valor da variável i
, e desta vez i
o valor da variável foi incrementado 9
.
Pronúncia Correta
wg := sync.WaitGroup{}
for i := 0; i < 9; i++ {
wg.Add(1)
go func(v int) {
fmt.Println(v)
wg.Done()
}(i)
}
wg.Wait()
复制代码
imprimir resultado
use grpool
Usar grpool é o mesmo que usar go, você precisa atribuir o valor da variável atual i a uma variável temporária que não será alterada e usar a variável temporária na função em vez de usar a variável diretamente i
.
Erro de código
wg := sync.WaitGroup{}
for i := 0; i < 9; i++ {
wg.Add(1)
_ = grpool.Add(func() {
fmt.Println(i) //打印结果都是9
wg.Done()
})
}
wg.Wait()
复制代码
imprimir resultado
código correto
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()
复制代码
imprimir resultado
Resumir
Através deste artigo, aprendemos que o papel do grpool é reutilizar goroutines para reduzir o consumo de desempenho de criação e destruição frequentes.
Também aprendi sobre os erros que são fáceis de cometer ao usar corrotinas e como resolver problemas com variáveis temporárias.
Uma digressão: os conceitos básicos do grpool: Pool, Worke, Job são exatamente os mesmos do sistema de despacho de pedidos que projetei antes.
afinal
Obrigado por ler, e bem-vindos a todos: like, favorito,moeda(focar em)! ! !