Pular pro conteúdo
Francisco Cidade
5 minutos de leitura

(WIP) Concorrência e Paralelismo com Golang - Select

Sumário

Select 🚀

alt text

O select é uma ferramenta poderosa para gerenciamento de múltiplos canais em Go, permitindo aguardar por operações de I/O e evitar bloqueios desnecessários. Compreender sua sintaxe, a importância do default e os comportamentos quando múltiplos cases estão prontos é fundamental para escrever um código concorrente robusto.

O que é o select? 🤔

Sintaxe

Quando utilizar o select

Exemplo prático

Considere dois channels; queremos aguardar o recebimento de dados de qualquer um deles:

package main

import (
	"fmt"
	"time"
)

func main() {
	ch1 := make(chan string)
	ch2 := make(chan string)
	
	// Simulando envio de dados após tempos diferentes
	go func() {
		time.Sleep(500 * time.Millisecond)
		ch1 <- "Mensagem do canal 1"
	}()
	
	go func() {
		time.Sleep(300 * time.Millisecond)
		ch2 <- "Mensagem do canal 2"
	}()
	
	// O select espera até que um dos channels esteja pronto para enviar o dado
	select {
		case msg1 := <-ch1:
			fmt.Println("Recebido:", msg1)
		case msg2 := <-ch2:
			fmt.Println("Recebido:", msg2)
		default:
			fmt.Println("Nenhum canal estava pronto.")
	}
	
	// O programa pode aguardar um pouco para ver a execução completa
	time.Sleep(1 * time.Second)
}

Neste exemplo, devido ao tempo de sleep, o case do ch2 será acionado primeiro, mas o default executaria imediatamente se nenhum canal estivesse pronto.

Uso do default

Exercícios com select

Exercício 1 – Recebendo do primeiro canal disponível

Exercício 2 – Envio e default

Exercício 3 – Time-out com select

Exercício 4 – Alternância entre múltiplos canais

Exercício 5 – Combinação: select com waitgroup

Erros mais comuns com select ⚠️

Falha em incluir um default quando necessário

Supor ordem determinística

Não lidar com o fechamento de channels

Usar o select inadequadamente em loops

Misturar cases com operações bloqueantes e não bloqueantes

Solução dos exercícios

Pra não ter que ficar rodando manualmente cada exercício, eu usei testes e exemplos testáveis.

Exercício 1:

// main.go
// main_test.go

Próximos passos!

Em seguida iremos abordar Mutex! Clique aqui para a parte 4!

Referências