Sin salida de goroutine en Go

Mientras SayHello() ejecuta como se esperaba, el goroutine no imprime nada.

 package main import "fmt" func SayHello() { for i := 0; i < 10 ; i++ { fmt.Print(i, " ") } } func main() { SayHello() go SayHello() } 

Cuando su función main() finaliza, su progtwig también finaliza. No espera a que terminen otros goroutines.

Citando de la especificación del lenguaje Go: Ejecución del progtwig :

La ejecución del progtwig comienza inicializando el paquete principal y luego invocando la función main . Cuando esa invocación de función retorna, el progtwig sale. No espera a que se completen otros goroutines (no main ).

Vea esta respuesta para más detalles.

Tienes que decirle a tu función main() que espere a que la función SayHello() comience como una rutina para completarse. Puede sincronizarlos con canales, por ejemplo:

 func SayHello(done chan int) { for i := 0; i < 10; i++ { fmt.Print(i, " ") } if done != nil { done <- 0 // Signal that we're done } } func main() { SayHello(nil) // Passing nil: we don't want notification here done := make(chan int) go SayHello(done) <-done // Wait until done signal arrives } 

Otra alternativa es indicar la finalización al cerrar el canal:

 func SayHello(done chan struct{}) { for i := 0; i < 10; i++ { fmt.Print(i, " ") } if done != nil { close(done) // Signal that we're done } } func main() { SayHello(nil) // Passing nil: we don't want notification here done := make(chan struct{}) go SayHello(done) <-done // A receive from a closed channel returns the zero value immediately } 

Notas:

Según sus ediciones / comentarios: si desea que las 2 funciones de ejecución de SayHello() impriman números "mixtos" al azar: no tiene garantía de observar dicho comportamiento. Nuevamente, vea la respuesta antes mencionada para más detalles. El modelo de memoria Go solo garantiza que ciertos eventos ocurran antes que otros eventos, no tiene garantía de cómo se ejecutan 2 rutinas simultáneas.

Puede experimentar con eso, pero sepa que el resultado no será determinista. Primero debe habilitar múltiples goroutines activos para que se ejecuten con:

 runtime.GOMAXPROCS(2) 

Y en segundo lugar, primero tiene que iniciar SayHello() como una rutina porque su código actual primero ejecuta SayHello() en la rutina principal y solo una vez que termina comienza la otra:

 runtime.GOMAXPROCS(2) done := make(chan struct{}) go SayHello(done) // FIRST START goroutine SayHello(nil) // And then call SayHello() in the main goroutine <-done // Wait for completion 

Alternativamente (a la respuesta de icza) puede usar WaitGroup desde el paquete de sync y la función anónima para evitar alterar el SayHello original.

 package main import ( "fmt" "sync" ) func SayHello() { for i := 0; i < 10; i++ { fmt.Print(i, " ") } } func main() { SayHello() var wg sync.WaitGroup wg.Add(1) go func() { defer wg.Done() SayHello() }() wg.Wait() } 

Para imprimir números simultáneamente, ejecute cada instrucción de impresión en una rutina separada como la siguiente

 package main import ( "fmt" "math/rand" "sync" "time" ) func main() { var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.Add(1) go func(fnScopeI int) { defer wg.Done() // next two strings are here just to show routines work simultaneously amt := time.Duration(rand.Intn(250)) time.Sleep(time.Millisecond * amt) fmt.Print(fnScopeI, " ") }(i) } wg.Wait() }