Programação Assíncrona em Go: Guia Completo para Iniciantes

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Programação Assíncrona em Go: Guia Completo para Iniciantes

\n\n

Programação assíncrona é uma abordagem na qual um programa pode executar várias tarefas simultaneamente, sem bloquear a execução do fluxo principal. Na linguagem Go (Golang), esse mecanismo é implementado de forma especialmente elegante e simples graças aos primitivos integrados: goroutines e canais (channels). Ao contrário de muitas outras linguagens, onde a assincronia exige callbacks complexos ou Promises, o Go oferece uma sintaxe concisa e ferramentas poderosas para trabalhar com concorrência.

\n\n

Neste guia, abordaremos os fundamentos da programação assíncrona em Go. Você aprenderá o que são goroutines, como criá-las e sincronizá-las usando canais, e como usar o operador select para trabalhar com vários canais. O material é voltado para iniciantes, portanto, todos os exemplos serão o mais simples e claros possível.

\n\n

O que são goroutines e como funcionam

\n\n

Uma goroutine é uma thread de execução leve, gerenciada pelo runtime do Go. Ao contrário das threads comuns do sistema operacional, as goroutines consomem muito menos recursos: a pilha de uma goroutine começa com alguns kilobytes e pode se expandir dinamicamente. Para iniciar uma goroutine, basta adicionar a palavra-chave go antes da chamada de função:

\n\n
package main\n\nimport (\n    "fmt"\n    "time"\n)\n\nfunc printMessage(msg string) {\n    for i := 0; i < 3; i++ {\n        fmt.Println(msg)\n        time.Sleep(100 * time.Millisecond)\n    }\n}\n\nfunc main() {\n    // Iniciando uma goroutine\n    go printMessage("Olá da goroutine!")\n    \n    // Função principal\n    printMessage("Olá do main!")\n    \n    // Aguardando a conclusão da goroutine\n    time.Sleep(1 * time.Second)\n}
\n\n

Neste exemplo, a função printMessage é executada duas vezes: uma como função normal e outra como goroutine. A execução ocorre de forma concorrente: as mensagens serão misturadas. Observe que, sem o time.Sleep no final do main, o programa terminará sem esperar a conclusão da goroutine. Para uma sincronização confiável, é melhor usar mecanismos específicos.

\n\n

Canais: transferência segura de dados entre goroutines

\n\n

Canais (channels) são "tubos" tipados através dos quais as goroutines podem trocar dados. Um canal é criado com a função make e o operador chan. Os dados são enviados para o canal com <- e recebidos dele com sintaxe semelhante.

\n\n

Vejamos um exemplo básico:

\n\n
package main\n\nimport "fmt"\n\nfunc sendData(ch chan string) {\n    ch <- "Dados da goroutine"\n}\n\nfunc main() {\n    // Criando um canal para strings\n    messageChannel := make(chan string)\n    \n    // Iniciando uma goroutine que envia dados\n    go sendData(messageChannel)\n    \n    // Recebendo dados do canal (bloqueia até receber)\n    message := <-messageChannel\n    \n    fmt.Println(message)\n}
\n\n

Aqui, a goroutine envia uma string para o canal, e o main aguarda seu recebimento. Importante: as operações com canais são, por padrão, bloqueantes. O envio para um canal é bloqueado até que os dados sejam recebidos, e vice-versa. Isso garante uma sincronização natural.

\n\n

Os canais podem ser bufferizados. O buffer permite enviar dados sem bloqueio, até que o buffer esteja cheio:

\n\n
// Criando um canal bufferizado com capacidade para 2 elementos\nbufferedChannel := make(chan string, 2)\n\n// Enviando dados sem bloqueio\nbufferedChannel <- "Primeiro"\nbufferedChannel <- "Segundo"\n\n// Agora podemos receber os dados\nfmt.Println(<-bufferedChannel)\nfmt.Println(<-bufferedChannel)
\n\n

Operador select: trabalhando com vários canais

\n\n

Quando você tem vários canais e deseja reagir àquele que estiver pronto primeiro, o operador select é a ferramenta ideal. Ele permite que uma goroutine aguarde múltiplas operações de canal simultaneamente, executando o caso que estiver disponível.

Blogs

Book Recommendations