Go Channels Tutorial

neste tutorial, nós vamos estar olhando para como você pode usar os canais dentro de suas aplicações baseadas em Go.

canais são tubos que ligam entre goroutines dentro de suas aplicações Go Based que permitem a comunicação e, posteriormente, a passagem de valores de e para variáveis.

são incrivelmente úteis e podem ajudá-lo a criar aplicações incrivelmente elevadas,altamente concorrentes em Go com o mínimo de espalhafato em comparação com outras línguas de programação. Isso não foi obra do acaso, quando a concepção de thelanguage, o núcleo de desenvolvedores decidiram que queriam concorrência dentro theirlanguage para ser cidadão de primeira classe e torná-lo tão simples para trabalhar com aspossible, sem ir muito longe e não permitindo que os desenvolvedores a liberdade theyneed para o trabalho.

a capacidade de criar sistemas concorrentes tão facilmente é algo que me atraiu para a linguagem em primeiro lugar, e devo dizer, tem sido um direito absoluto até agora.Nota-eu recomendaria dar uma olhada no meu outro tutorial ongoroutines se você quiser aprender mais sobre goroutinas.

Objetivos

no final deste tutorial, você irá:

  • Ter uma sólida compreensão de como a teoria por trás de canais
  • Ser capaz de criar simples simultâneas aplicações que utilizam canais

pré-Requisitos

para concluir este tutorial, você vai precisar de ter sido followingprerequisites:

  • Você vai precisar Ir instalado em sua máquina.

Tutorial de vídeo

se desejar, este tutorial está disponível em formato de vídeo.

A Teoria

A ideia de canais não é nada de novo, assim como muitos de Go concurrencyfeatures, esses conceitos foram trazidos para a frente dos gostos de Hoare’sCommunicating Processos Sequenciais (1978), CSP, e mesmo a partir de thelikes de Dijkstra vigiado comandos (1975).

os programadores da Go, No entanto, fizeram da sua missão apresentar estes conceitos de uma forma tão simples quanto possível para permitir que os programadores criassem aplicações mais correctas e altamente concorrentes.

um exemplo simples

vamos começar por ver como podemos construir um exemplo muito simples de como isto funciona. Vamos primeiro criar uma função que desaparece e calcula o valor anarbitrário, Aleatório e passa-a de volta para uma variável de canal chamadavalues:

main.vamos desectar o que aconteceu aqui. Em nossa função main(), nós chamamosvalues := make(chan int), esta chamada efetivamente criou o nosso novo canal para que pudéssemos posteriormente usá-lo dentro do nosso CalculateValue goroutine.Nota-usámos make ao instanciar o nosso canal values como, likemaps e fatias, os canais devem ser criados antes de serem utilizados.

depois de criarmos o canal, chamámos então defer close(values) o que conferiu o encerramento do nosso canal até ao fim da execução da nossa função main(). Isto é normalmente considerado uma boa prática para garantir que nós arrumamos depois de nós mesmos.Após a nossa chamada paradefer, iniciamos o nosso único goroutine: CalculateValue(values) passando no nosso recém-criado canal values como itsparameter. Dentro da nossa função CalculateValue, calculamos um único valor aleatório entre 1-10, imprimimos isto e depois enviamos este valor para o nosso canal valueschamando values <- value.

saltando de volta para a nossa função main(), então chamamos value := <-values que recebe um valor do nosso canal values.Nota-observe como quando executamos este programa, ele não termina imediatamente. Isto porque o ato de enviar e receber de um bloqueio de canal. A nossa função main() bloqueia até receber um valor do nosso canal.

após a execução deste código, você deve ver o resultado parecido com este:

$ go run main.goGo Channel TutorialCalculated Random Value: {} 77

resumo:

myChannel := make(chan int) – cria myChannel que é um canal do tipoint

channel <- value – envia um valor para um canal

value := <- channel – recebe um valor a partir de um canal

Então, instanciar e o uso de canais no seu programa parece fairlystraightforward tão longe, mas o que sobre em cenários mais complexos?

canais não Barrados

usando um tradicional channel dentro das suas goroutinas pode, por vezes, levar a questões com comportamento que pode não estar à espera. Com canais tradicionaisunbuffered, sempre que um goroutino envia um valor para este canal, que goroutine irá posteriormente bloquear até que o valor seja recebido do canal.Vamos ver isto num exemplo real. Se dermos uma olhada no código abaixo, é muito semelhante ao código que tínhamos anteriormente. No entanto, alargámos a nossa função CalculateValue() para realizar um fmt.Println depois de ter enviado o seu valor calculado para o canal.

na nossa função main(), adicionámos uma segunda chamada parago CalculateValue(valueChannel) por isso devemos esperar 2 valores enviados para este canal em sucessão muito rápida.

main.ir

no Entanto, quando você executar este procedimento, você deve ver que apenas a nossa primeira goroutines’ finalprint instrução é executado:

go run main.goGo Channel TutorialCalculated Random Value: {} 1Calculated Random Value: {} 71Only Executes after another goroutine performs a receive on the channel

A razão para esta é a nossa chamada para c <- value foi bloqueado em nosso secondgoroutine e, posteriormente, o main() função conclui sua execução beforeour segundo goroutine tem a chance de completar a sua própria execução.

canais tamponados

a maneira de contornar este comportamento de bloqueio é usar algo chamado canal abuffered. Estes canais tamponados são essencialmente filas de um dado tamanho que pode ser usado para a comunicação cross-goroutine. A fim de criar abuffered canal, em oposição a uma unbuffered canal, nós fornecemos uma capacityargument para o nosso make comando:

bufferedChannel := make(chan int, 3)

alterando para um buffer do canal, a nossa operação de envio, c <- value onlyblocks dentro do nosso goroutines caso o canal de ser completo.

vamos modificar nosso programa existente para usar um canal buffer e dar uma olhada na saída. Repare que adicionei uma chamada para time.Sleep() na parte inferior da nossa função main() a fim de bloquear preguiçosamente a nossa função main() o suficiente para permitir que as nossas goroutinas completem a execução.

main.go

agora, quando executarmos isto, devemos ver que o nosso segundo goroutino prossegue a sua execução, independentemente do facto de uma segunda recepção não ter sido impedida na nossa função main(). Graças ao time.Sleep(), podemos ver claramente a diferença entre os canais não barrados e a sua natureza de bloqueio e os nossos canais baralhados e a sua natureza de não bloqueio (quando não completa).

Go Channel TutorialCalculated Random Value: {} 1Calculated Random Value: {} 77This executes regardless as the send is now non-blockingThis executes regardless as the send is now non-blocking

Conclusão

Assim, neste razoavelmente longa tutorial, conseguimos aprender sobre o variousdistinct tipos de canais dentro de Ir. Descobrimos as diferenças entre canais baralhados e não baralhados e como podemos usá-los para nossa vantagem em nossos programas de go concorrentes.Se gostou deste tutorial, sinta-se à vontade para me informar na secção de comentários abaixo. Se você tem alguma sugestão sobre o que eu poderia fazer melhor then eu adoraria ouvi-los na seção de comentários abaixo!Se gostou deste artigo e deseja aprender mais sobre a concorrência em Go, então recomendo que verifique os nossos outros artigos sobre concorrência.:

  • Go Mutex Tutorial
  • Go Goroutines Tutorial
  • Go sync.Tutorial Do Grupo De Espera

Deixe uma resposta

O seu endereço de email não será publicado.

Previous post 9 curiosidades Sobre Gatinhos
Next post deve pintar ou manchar armários? Prós e contras de cada