Gorutines es la capacidad que tiene GO para hacer uso de hilos o múltiples cores del CPU .
Al poner la palabra reservada go adelante de la función , en automático dicha función se ejecutará en otro hilo.
Es necesario que las Gorutines terminen antes que la ejecución del hilo principal de main, ya que de lo contrario se cancela la ejecución de las Gorutines
Con las Gorutines se reparte el proceso en varios hilos y en varios Cores del procesador .
Con los Channels podemos tener el control de la Gorutines .
Buen aporte
time tambien cuenta con una constante para Segundo, el Sleep tambien puede quedar de la siguiente manera:
time.Sleep(10* time.Second)
Mas informacion aqui
Buen aporte.
Comparto el código del ejercicio:
package main
import"fmt"import"time"func helloGo(index int){ fmt.Println("Hola soy un print en la Go routine #", index)}func forGo(n int){fori:=0; i < n; i++{ go helloGo(i)}}func main(){forGo(500)forGo(400) time.Sleep(1000* time.Millisecond);}
Para que casos puedo usar las goroutines?
Cuando necesitas hacer cálculos por ejemplo puedes enviar eso a una gorutine y no bloquear del todo la ejecución de tu programa.
Desplegar varios servidores
Les comparto un codigo que hice antes de ver este video, y en donde se aprecía mejor la diferencia entre ejecutar secuencialmente y con concurrencia mediante las goroutines,
package main
import("runtime""sync""time""fmt")func main(){//sinConcurrencia()conConcurrencia()}func sinConcurrencia(){op:=func(i int){ fmt.Println("Operacion", i,"Segundo :",time.Now().Format("5")) time.Sleep(3* time.Second) fmt.Println("Operacion", i,"Segundo :", time.Now().Format("5")) fmt.Println("Numero de rutinas :", runtime.NumGoroutine())}inicio:= time.Now()fori:=1; i <3; i++{op(i)} fmt.Println("Se ejecutó en ", time.Since(inicio))}func conConcurrencia(){var mayor int
mayor=1var wg sync.WaitGroupop:=func(i int){if runtime.NumGoroutine()> mayor { mayor=runtime.NumGoroutine() fmt.Println(mayor)} defer wg.Done()//Indica que esa rutina se terminó fmt.Println("Numero de rutinas :", runtime.NumGoroutine()) fmt.Println("Operacion", i,"Segundo :",time.Now().Format("5")) time.Sleep(3* time.Second) fmt.Println("Operacion", i,"Segundo :", time.Now().Format("5"))}// fmt.Println("Numero de rutinas :", runtime.NumGoroutine())inicio:= time.Now()fori:=1; i <3; i++{ wg.Add(1)//Indica la adicion de una nueva rutina para su posterior espera go op(i)}//Espera que todas las rutinas finalizen wg.Wait() fmt.Println("Se ejecutó en ", time.Since(inicio)) fmt.Println("Mayor numero de rutinas utilizadas al mismo tiempo:", mayor)}
La libreria sync nos permite esperar la finalizacion de las rutinas para continuar el programa
Concurrencia sin paralelismo:
1 dispensador de gaseosa y 30 personas.
15 goroutines en mi 486dx de 32 MHZ (1 procesador)
Concurrencia con Paralelismo:
n dispensadores de gaseosa y 30 personas.
15 goroutines en un Procesador Ryzen Octacore
Investigando un poco encontré que los goroutines no son específicamente hilos, de hecho hay algunas diferencias entre ambos:
Las goroutines son extremadamente baratos en comparación con los hilos. Solo tienen unos pocos kb de tamaño de pila y la pila puede crecer y reducirse según las necesidades de la aplicación, mientras que en el caso de los hilos, el tamaño de la pila debe especificarse y es fijo.
Las Goroutines se multiplexan a una menor cantidad de subprocesos del sistema operativo. Puede haber solo un hilo en un programa con miles de Goroutines. Si alguna Goroutine en ese bloque de subprocesos dice esperar la entrada del usuario, se crea otro subproceso del sistema operativo y las Goroutines restantes se mueven al nuevo subproceso del sistema operativo. Todos estos son atendidos por el tiempo de ejecución y nosotros, como programadores, somos abstraídos de estos detalles intrincados y se les da una API limpia para trabajar con concurrencia.