🥇 Uso de select para el manejo de múltiples canales.

Supongamos que tenemos múltiples múltiples rutinas, y deseamos capturar cual de ellas es la primera en responder. Para dicho caso podemos utilizar un canal para cada una de ellas, en cominación con select que haga referencia a cada uno de los canales.

Supongamos que estamos en una hipodromo, y cada uno de los caballos representa una función. Cada función esta asignada en este caso a una rutina, pues los caballos corren todos al mismo tiempo, pero solo deseamos saber cual es el primero en llegar.

package main

import (
    "fmt"
    "time"
)

func caballo1(can chan string) {
    time.Sleep(time.Second * 3)
    can <- "Caballo 1 completo la carrera"
}

func caballo2(can chan string) {
    time.Sleep(time.Second * 2)
    can <- "Caballo 2 completo la carrera"
}

func caballo3(can chan string) {
    time.Sleep(time.Second * 4)
    can <- "Caballo 3 completo la carrera"
}

func main() {
    can1 := make(chan string)
    can2 := make(chan string)
    can3 := make(chan string)

    go caballo1(can1)
    go caballo2(can2)
    go caballo3(can3)

    select {
    case ganador := <-can1:
        fmt.Println(ganador)
    case ganador := <-can2:
        fmt.Println(ganador)
    case ganador := <-can2:
        fmt.Println(ganador)
    }
}

Primero recreamos 3 funciones que reciben un canal como argumento, y escriben un string sobre este.

func caballo1(can chan string) {
    time.Sleep(time.Second * 3)
    can <- "Caballo 1 completo la carrera"
}

func caballo2(can chan string) {
    time.Sleep(time.Second * 2)
    can <- "Caballo 2 completo la carrera"
}

func caballo3(can chan string) {
    time.Sleep(time.Second * 4)
    can <- "Caballo 3 completo la carrera"
}

Dentro de la función main creamos tres canales, cada uno de ellos será utilizado para cada uno de los parametros de cada función.

can1 := make(chan string)
can2 := make(chan string)
can3 := make(chan string)

Para realizar la ejecución de las tres funcionen en paralelo, a cada una la alojamos en una rutina.

go caballo1(can1)
go caballo2(can2)
go caballo3(can3)

Finalmente podemos utilizar un select para asociar cada posible canal, el primero que retorne una salida sera el que imprimamos.

select {
    case ganador := <-can1:
        fmt.Println(ganador)
    case ganador := <-can2:
        fmt.Println(ganador)
    case ganador := <-can2:
        fmt.Println(ganador)
}

En este caso, como el caballo que tarda menos tiempo en completar la carrera es el caballo 2, nuestra salida es.

Caballo 2 completo la carrera
Canales como argumentos. Manejo de multiples canales y timeouts.
comments powered by Disqus