Múltiplos channels e a cláusula select

Dando continuidade ao nosso estudo de goroutines e channels, nesse post vamos falar sobre uma cláusula pouco utilizada.

Antes de começar, vou deixar os links para os outros posts caso você tenha perdido algum da série.

A cláusula select é utilizada para que uma função consiga trabalhar com múltiplos channels. Ela bloqueia a execução da função até que um dos channels esteja pronto para ser executado. Caso mais de um channel esteja pronto para ser executado, ela selecionará de forma aleatória qual executar.

Para tentar ficar um pouco mais claro, vamos escrever um pequeno programa para ilustrar o comportamento.

Primeiramente vamos criar uma função que vai ficar somando números aleatórios infinitamente. Essa função receberá 2 channels por parâmetro, sendo um para comunicar o valor atual da somatória e outro para receber o sinal de exit.

func sum(total chan int, exit chan bool) {
    valor := rand.Intn(20)
    for {
        select {
            case total <- valor:
                valor += rand.Intn(20)

            case <-exit:
                fmt.Println("exit :)")
                return
        }
    }
}

Mesmo a função tendo um loop infinito, o channel exit irá controlar o fim da sua execução, já que quando ele receber um valor, o return será executado, matando assim a execução do loop.

Outro ponto que precisamos estar atentos ao escrever a função principal é que o channel total não terá buffer. Dessa forma, a soma do próximo número aleatório só irá acontecer após alguma outra rotina ler a última soma executada.

Agora vamos escrever a função principal para utilizar essa função de soma.

func main() {
    total := make(chan int)
    exit := make(chan bool)

    go func() {
        for i := 0; i < 10; i++ {
            fmt.Println(<-total)
        }

        exit <- true
    }()

    sum(total, exit)
}

Na nossa função principal, criamos uma goroutine anônima para controlar a execução da função sum. Como limitamos o loop em 10 voltas e a cláusula select bloqueia a execução até que um dos channels esteja pronto, o número de voltas do loop da função sum deve ser muito parecido com o da nossa função anônima.

Para testar nosso código é só executar um go run main.go. A saída será algo similar a isso:

1
8
15
34
35
53
58
58
74
74
exit :)

Deixem suas dúvidas nos comentários.

Até a próxima!


Subscreva

Fique por dentro de tudo o que acontece no mundo Go.

Um comentário sobre “Múltiplos channels e a cláusula select

Deixe uma resposta