Aula 25 – Tutorial Golang – Goroutines

Aula 25 – Tutorial Golang – Goroutines

Tutorial Golang - Goroutines

Tutorial Golang – Goroutines

Pacote Programador Fullstack

Pacote Programador Fullstack

Página principal do blog

Todas as aulas desse curso

Aula 24                        Aula 26

Redes Sociais:

facebook

Meus links de afiliados:

Hostinger

Digital Ocean

One.com

Melhore seu NETWORKING

https://digitalinnovation.one/

Participe de comunidades de desenvolvedores:

Fiquem a vontade para me adicionar ao linkedin.

E também para me seguir no https://github.com/toticavalcanti.

Código final da aula:

https://github.com/toticavalcanti

Canais do Youtube

Toti

Backing Track / Play-Along

Código Fluente

Putz!

Vocal Techniques and Exercises

PIX para doações

PIX Nubank

PIX Nubank

Aula 25 – Tutorial Golang – Goroutines

Goroutines

O que são Goroutines?

Goroutines são funções ou métodos que são executados simultaneamente com outras funções ou métodos.

Goroutines podem ser consideradas threads leves.

Em Go, todo programa tem pelo menos uma goroutine: a goroutine main.

O custo de criar uma Goroutine é pequeno quando comparado a uma thread.

Portanto, é comum que os aplicativos Go tenham milhares de Goroutines sendo executadas simultaneamente.

Vantagens de Goroutines sobre as threads

Goroutines são extremamente baratas quando comparadas as threads.

Elas têm apenas alguns kb de tamanho na pilha, e a pilha pode crescer e diminuir de acordo com as necessidades da aplicação, enquanto no caso de threads o tamanho da pilha deve ser especificado e é fixo.

As Goroutines são multiplexadas para um número menor de threads no SO.

Pode haver apenas uma thread em um programa com milhares de Goroutines.

Se qualquer Goroutine nesse bloco de thread disser que está aguardando entrada do usuário, outra thread no sistema operacional, será criada, e as Goroutines restantes serão movidas para a nova thread do SO.

Tudo isso é cuidado em tempo de execução e nós, como programadores, somos abstraídos desses detalhes intrincecos e recebemos uma API limpa para trabalhar com simultaneidade.

Goroutines se comunicam usando canais.

Os canais, por design, evitam que as condições de corrida aconteçam ao acessar a memória compartilhada usando Goroutines.

Os canais podem ser pensados ​​como um tubo através do qual as Goroutines se comunicam.

Como iniciar uma Goroutine?

Prefixe a chamada de função ou método com a palavra-chave go e você terá uma nova Goroutine rodando simultaneamente.

Vamos criar uma Goroutine? 🙂


package main

import (  
    "fmt"
)

func hello() {  
    fmt.Println("Hello world goroutine")
}
func main() {  
    go hello()
    fmt.Println("main function")
}

go hello() logo no início da main(), inicia uma nova Goroutine.

Agora a função hello() será executada simultaneamente com a função main().

A função main() é executada em sua própria Goroutine e é chamada de Goroutine principal.

Execute este programa e você terá uma surpresa!

Este programa produz apenas o texto informando: função principal.

Saída:

main function

O que aconteceu com a Goroutine que começamos?

Precisamos entender as duas principais propriedades das Goroutines para entender por que isso acontece.

Quando uma nova Goroutine é iniciada, a chamada da Goroutine retorna imediatamente.

Ao contrário das funções, o controle não espera que a Goroutine termine de executar.

O controle retorna imediatamente para a próxima linha de código após a chamada de Goroutine e quaisquer valores de retorno do Goroutine são ignorados.

A Goroutine principal deve estar em execução para que qualquer outra Goroutine seja executada.

Se a Goroutine principal for encerrada, o programa será encerrado e nenhuma outra Goroutine será executada.

Acho que agora você será capaz de entender por que nossa Goroutine não funcionou.

Após a chamada para go hello(), o controle retornou imediatamente para a próxima linha de código sem esperar que o hello goroutine termine e imprimiu a função main().

Em seguida, a Goroutine principal foi encerrada, pois não há outro código para executar e, portanto, a Goroutine hello() não teve a chance de ser executada.

Vamos corrigir isso agora!


package main

import (  
    "fmt"
    "time"
)

func hello() {  
    fmt.Println("Hello world goroutine")
}
func main() {  
    go hello()
    time.Sleep(1 * time.Second)
    fmt.Println("main function")
}

Na parte do código onde tem: time.Sleep(1 * time.Second), chamamos o método Sleep do pacote time, que faz a rotina go na qual ele está sendo executada, dormir(sleep).

Neste caso, a goroutine principal é adormecida por 1 segundo.

Agora a chamada para go hello(), tem tempo suficiente para ser executada antes que a Goroutine principal termine.

Este programa primeiro imprime a goroutine Hello world, espera 1 segundo e depois imprime a função main.

Essa maneira de usar o Sleep na Goroutine principal para esperar que outras Sleep terminem sua execução, é um hack que estamos usando para entender como as Goroutines funcionam.

Vamos ver mais um exemplo:


package main

import (
    "fmt"
)

func main() {

    hello("Martin")
    hello("Lucia")
    hello("Michal")
    hello("Jozef")
    hello("Peter")
}

func hello(name string) {

    fmt.Printf("Hello %s!\n", name)
}

Nesse código acima, temos a chamada normal, síncrona, da função hello(), agora vamos ver o mesmo código com Gourotine.


package main

import (
	"fmt"
)

func hello(name string) {

	fmt.Printf("Hello %s!\n", name)
}

func main() {

	go hello("Martin")
	go hello("Lucia")
	go hello("Michal")
	go hello("Jozef")
	go hello("Peter")
}

Veja que não houve tempo de imprimir, porque a Goroutine principal finalizou muito rápido, sem esperar a execução das chamadas da função hello().

Para fazer a Goroutine principal esperar, ao invés de usar o recurso do Sleep como fizemos antes, vamos adicionar fmt.Scanln() para o programa ficar esperando alguma entrada do usuário para encerrar a execução.


package main

import (
	"fmt"
)

func hello(name string) {

	fmt.Printf("Hello %s!\n", name)
}

func main() {

	go hello("Martin")
	go hello("Lucia")
	go hello("Michal")
	go hello("Jozef")
	go hello("Peter")
        fmt.Scanln()
}

Canais

Os canais podem ser usados para bloquear a Goroutine principal até que todas as outras Goroutines terminem sua execução.

E é justamente canais, que veremos na próxima aula.

É isso pessoal, fico por aqui!

Até mais. 🙂

Página principal do blog

Todas as aulas desse curso

Aula 24                        Aula 26

Meus links de afiliados:

Hostinger

Digital Ocean

One.com

Obrigado e bons estudos. 😉

About The Author
-

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>