Golang: Desmistificando 채널 - Exemplo concreto
12304 단어 gotutorialbraziliandevsprogramming
구체적인 채널 사용 예
Vamos supor que você tenha um slice de URLs de arquivos e queira baixar todos de forma simultânea.
Você pode começar implementando uma solução sequencial, e depois fazer isso concorrente com goroutines, e por último usar os os channels para esperar cada download terminar e comunicar que eles finalizaram.
Fazendo os는 순차 형식으로 다운로드합니다.
Digamos que você tenha um slice com os arquivos que quer baixar:
urls := []string{
"http://files.com/file1.png",
"http://files.com/file2.png",
"http://files.com/file3.png",
}
Para fazer or download deles, você pode criar uma função
download
que recebe URL do arquivo e faz o download.Para simular o download, vamos fazer uma função que espera um tempo aleatório entre 0 e 3 segundos.
func download(url string) {
r := rand.Intn(4)
time.Sleep(time.Duration(r) * time.Second)
}
Agora, vamos fazer 또는 파일 형식 순차 파일 다운로드:
for _, url := range urls {
download(url)
fmt.Println("concluído:", url)
}
O resultado vai ser esse:
concluído: http://files.com/file1.png
concluído: http://files.com/file2.png
concluído: http://files.com/file3.png
다운로드할 수 있는 프로그램이 3개 단계가 없으며 총 9개 단계가 있습니다.
Se conseguirmos fazer isso de forma simultânea, o pior cenário vai levar 3 segundos no total.
Usando goroutines para fazer 다운로드 동시 다운로드
finished := make(chan string)
Poderia ser de outro tipo, mas nesse caso vou mandar a URL do download que finalizou, por isso vou usar um
chan string
.func download(url string) {
...
}
func main () {
urls := []string{
...
}
finished := make(chan string)
for _, url := range urls {
// isso é feito pra redefinir a url nesse escopo
url := url
go download(url)
}
}
Isso não vai funcionar, porque a goroutine
main
Vai finalizar primeiro e vai encerrar o programa.func download(url string) {
...
}
func downloadAndNotify(url string, ch chan string) {
download(url)
// agora em vez de só baixar em outra goroutine, estamos
// enviando a url do download finalizado para o channel
ch <- url
}
func main () {
...
for _, url := range urls {
url := url
go downloadAndNotify(url, finished)
}
// obs.: o programa vai continuar encerrando antes de fazer os downloads
}
func main () {
...
for _, url := range urls {
url := url
go downloadAndNotify(url, finished)
}
// sabemos que o números de resultados vai ser igual ao
// tamanho de urls, então podemos fazer esse for para repetir len(urls) vezes
for range urls {
// recebemos um resultado do channel
// lembre-se, esse receber vai bloquear até que alguma goroutine envie algo
url := <-finished
fmt.Println("concluído:", url)
}
// como o loop anterior repete 3x, todos os resultados das 3 goroutines
// são lidos, e a main finaliza quando todos os downloads terminam
}
결과:
concluído: http://files.com/file2.png
concluído: http://files.com/file1.png
concluído: http://files.com/file3.png
Podemos também usar uma função anônima no lugar do
downloadAndNotify
, eo código completeto ficaria assim:package main
import (
"fmt"
"math/rand"
"time"
)
func download(url string) {
r := rand.Intn(4)
time.Sleep(time.Duration(r) * time.Second)
}
func main() {
urls := []string{
"http://files.com/file1.png",
"http://files.com/file2.png",
"http://files.com/file3.png",
}
finished := make(chan string)
for _, url := range urls {
url := url
go func() {
download(url)
finished <- url
}()
}
for range urls {
url := <-finished
fmt.Println("concluído:", url)
}
}
Reference
이 문제에 관하여(Golang: Desmistificando 채널 - Exemplo concreto), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/tutorial_livre/golang-desmistificando-channels-2pkk텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)