🥇 Comunicación mediante canales.

Ahora vamos a volver a utilizar el ejemplo anterior en donde simulamos la lectura de un archivo grande…

package main

import (
    "fmt"
    "time"
)

func leerArchivo() string {
    time.Sleep(time.Second * 5)
    return "Datos del archivo"
}

func main() {
    go func() {
        datos := leerArchivo()
        fmt.Println(datos)
    }()
    fmt.Println("Continuar con la ejecución")
    time.Sleep(time.Second * 10)
}

Vamos a reemplazar el bloqueo de 10 segundos, por uno que solo espera a que la rutina se complete.

package main

import (
    "fmt"
    "time"
)

func leerArchivo() string {
    time.Sleep(time.Second * 2)
    return "Datos del archivo"
}

func main() {
    miCanal := make(chan string)
    go func() {
        miCanal <- leerArchivo()
    }()
    fmt.Println(<-miCanal)
    fmt.Println("Continuar con la ejecución")
}

Si ejecutamos el script, el resultado es el mismo, la diferencia es que en lugar de bloquear mediante un sleep, nuestro programa se bloquea en cuanto a miCanal se le asigna un valor.

Para crear un canal de tipo string, es decir que reciba este tipo de valores utilizamos la instrucción…

miCanal := make(chan string)

Lo siguiente que sucede, es que el programa ejecuta una rutina en segundo plano, que asigna un valor al canal unos segundos despues, cuando se lee de forma completa el archivo.

go func() {
    miCanal <- leerArchivo()
}()

Pero antes que esto suceda, se ha intentado leer un valor del canal.

fmt.Println(<-miCanal)

Al no tener un valor aun asignado, el programa genera un bloqueo, que solo se libera cuando el canal recibe un valor… en este caso dentro de la rutina.

Canales. Canales y buffers.
comments powered by Disqus