Golang - Trabalhando com Canais, um passo além do básico.
우마 브레베 히스토리아...
Estava eu ajudando um colega com uma tarefa envolvendo tarefas assíncronas com golang. "Qual a melhor forma de fazer "x"coisa?". Nesse momento me vi diante de umavasidão de possibilidades de resolver aquele problema. 만족감을 느끼기 위해 무엇을 설명해야 합니까?
아이디어 컴파일 솔루션
Havia lido tempos atrás essa solução que o autor também não atribuía a si, novidade na programação (só que não!). O artigo era o seguinte MULTIPLEXING CHANNELS IN GO , aconselho que leiam se quiserem aprofundar em alguns outros tópicos como canais.
Seguir apresentarei de forma bem direta a ideia de multiplexação.
자만심:
Estamos falando da possibilidade de agregar um conjunto de canais à um único canal. Dessa forma podemos convergir os dados à um único ponto que será a retomada da sincronicidade do nosso código.
Um multiplexador (abreviação: MUX), por vezes denominado pelos anglicismos multiplexer ou multiplex, é um dispositivo que seleciona as informações de duas ou mais fontes de dados num único canal. São utilizados em situações onde o custo de implementação de canais separados para cada fonte de dados é maior que o custo e a inconveniência de utilizar as funções de multiplexação/demultiplexação. - Wikipedia. Repare nas imagens.
Vamos ao código
Seguiremos os seguintes passos:
seguintes premissas로 간주하십시오:
// Tipo gerado para cada task poderíamos ter uma struct aqui
type Task int
// Tipo gerado para cada result poderíamos ter uma struct aqui
type Result int
// Função que representa um tempo de execução qualquer
// para finalização da tarefa do worker
func asyncSimulation(t Task) int {
time.Sleep(1 * time.Second)
return (int(t) * int(t))
}
0 - Nossa Função 메인:
func main() {
// Trabalharemos com 10 tasks para serem completadas
tasks := taskGenerator(1, 10)
results := make(chan Result)
// Esse wait group servirá para controlar o fechamento
// do canal de result e evitar deadlocks
wg := &sync.WaitGroup{}
// 5 workers serão utilizados nesse exemplo
for i := 0; i < 5; i++ {
wg.Add(1)
worker(tasks, results, wg)
}
// Verificamos o momento que todos os workers
// terminarem de trabalhar
verifyEnd(results, wg)
// Recebemos todos os resultados no canal result
// e imprimimos á medida que são resolvidos
resultAggregator(results)
}
1 - 에스팔하멘토의 재미:
Essa é a função responsável por alimentar o canal de task com as task que serão executadas.
버퍼가 교착 상태에 빠지기 전에 Numa Goroutine에 귀속되는 데 필요한 채널을 결정하는 이유는 무엇입니까?
func taskGenerator(start int, end int) <-chan Task {
tasks := make(chan Task)
go func() {
for i := start; i < end; i++ {
tasks <- Task(i)
}
close(tasks)
}()
return tasks
}
2 - Trabalhando com mais de um Worker:
Para trabalharmos com mais de um worker precisamos também gerenciar o fechamento do canal de results, para isso definimos um wait group para os workers
func worker(tasks <-chan Task, result chan<- Result, wg *sync.WaitGroup) {
go func() {
for task := range tasks {
result <- Result(asyncSimulation(task))
}
wg.Done()
}()
}
func verifyEnd(results chan<- Result, wg *sync.WaitGroup) {
go func() {
wg.Wait()
close(results)
}()
}
3 - A função de agregação:
Utilizamos essa função para receber todos os dados repassados para o canal de results e posteriormente somamos e mostramos eles na tela
func resultAggregator(res <-chan Result) {
sum := 0
totalResults := 0
for res := range res {
fmt.Printf("received result %v\n", res)
sum += int(res)
totalResults += 1
}
fmt.Printf("total os squares received: %d\n", totalResults)
fmt.Printf("sum of squares: %d", sum)
}
결과 분석
// Após 1 segundo recebemos os primeiros 5 resultados
// tempo gasto pelos 5 workers para processar as primeiras
// 5 tasks
received result 16
received result 9
received result 4
received result 0
received result 1
// Após mais 1 segundo recebemos os próximos 5 resultados
// tempo gasto pelos 5 workers para processar as últimas
// 5 tasks
received result 36
received result 25
received result 49
received result 64
received result 81
// impressão das demais informações do agregador
total os squares received: 10
sum of squares: 285
응용 프로그램 확장:
Esse conceito de multiplexação é apenas um dentre vários que podemos utilizar para garantir o trabalho de forma assíncrona para solução de diversos problemas. Sua aplicação vai desde requisições para APIs externas até execução de algoritmos custosos em segmentos menores.
폰테스
Reference
이 문제에 관하여(Golang - Trabalhando com Canais, um passo além do básico.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/lfsmariz/golang-trabalhando-com-canais-um-passo-alem-do-basico-nd5텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)