Golang: Desmistificando 채널 - Conceito e sintaxe
소개
Resolvi fazer esse texto porque no meu primeiro contato com channels eu não entendi muito bem como funcionava, daí eu semper fugia para o
WaitGroup
또는 fazia alguma Mutex
para tentar resolver.Fiz esse texto com o objetivo de deixar mais claro como usar channels e como entender os problemas comuns que você vai encontrar ao usar o channel de forma errada.
O que é e para que serve?
Channel, ou canal, é uma ferramenta nativa do para comunicar e sincronizar goroutines.
이 채널은 다양한 고루틴을 사용할 때 사용할 수 있는 뮤텍스를 사용할 수 없도록 주의를 기울이고 있습니다.
com 채널 você consegue facilmente fazer coisas como:
Criando 및 usando 채널
Para criar 음 채널, fazemos:
func main() {
ch := make(chan int)
}
O 채널은 기본적으로 다음과 같습니다:
int
, string
, struct{}
e outros.Esse tipo é o tipo de dado que vai ser enviado e recebido pelo canal.
Ao enviar uma informação para um channel, o que o que o outro lado recebe é uma cópia do dado.
Dessa forma você evita problemas de uma goroutine alterar o mesmo dado que outra goroutine pode estar lendo.
Para enviar informações para um channel, fazemos:
func main() {
ch := make(chan string)
ch <- "Shakespeare"
}
Para receber do channel, fazemos:
func main() {
ch := make(chan string)
// recebendo de um channel e descartando valor
<-ch
// recebendo de um channel e guardando numa variável
name := <-ch
}
어떤 기능이 있습니까?
Se você rodar qualquer um dos códigos do exemplo anterior, vai acontecer isso:
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.main()
main.go:5 +0x31
exit status 2
os 채널은 사용자가 수신할 수 있는 문제를 해결하기 위해 고루틴 실행을 일시 중지할 수 있습니다. Ou seja, a goroutine que tentar enviar vai esperar até que outra receba, e da mesma forma a goroutine que tentar receber vai esperar até que outra envie.
No caso acima quando eu tento enviar para um channel, eu pauso a goroutine
main
para esperar que outra goroutine leia o que enviei, mas como não tem outra goroutine rodando, a main
vai ficar esperando "para sempre"(deadlock
) ).O 런타임은 Go percebe que esse programa vai ficar parado indeterminadamente, porque todas as goroutines estão "dormindo"(
all goroutines are asleep
), então ele encerra o programa com um código de erro.O mesmo acontece no segundo example.
버퍼링된 채널에 존재하는 Também a gente enviar para um canal uma quantidade X de dados antes que ele comece a bloquear a goroutine, mas vamos ver isso mais para frente.
우산도 채널 수정
Para corrigir o problema do deadlock anterior, vamos criar outra goroutine que lê do channel, enquanto a goroutine
main
vai enviar para o channel.package main
import (
"fmt"
)
func main() {
ch := make(chan int)
// obs. 1: 'go' vai fazer com que essa função seja executada numa
// nova goroutine, então ler do channel não vai bloquear a main
go func() {
// obs. 2: eu não preciso passar o ch como parâmetro da função
// porque o ch está no da main escopo
<-ch
}()
// a goroutine main vai esperar até que consiga enviar
ch <- 12
fmt.Println("Fim")
}
Se você está confuso com
ch <- 12
e <-ch
, você pode pensar que a seta aponta para onde o dado está fluindo.// o dado está saindo do channel ch (receber) e sendo descartado
<-ch
// o dado está saindo do channel ch (receber) e sendo atribuído à variável x
x := <-ch
// o dado 12 está indo para o channel ch (enviar)
ch <- 12
Reference
이 문제에 관하여(Golang: Desmistificando 채널 - Conceito e sintaxe), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/tutorial_livre/golang-desmistificando-channels-4n7h텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)