waitgroup go goroutine

waitgroup - go channels



¿Por qué se requiere time.sleep para ejecutar ciertos goroutines? (3)

Debido a que el programador de rutina de goroutine no es preventivo, tus goroutines tienen que ceder el control antes de que se ejecute otro goroutine. Una forma de ceder el control es con el time.Sleep . time.Sleep . Otra forma es con runtime.Gosched() .

Aquí está el tutorial modificado para usar Gosched (): http://play.golang.org/p/jQ9mlGYXXE

Esta es una lección útil para entender los goroutines. Sin embargo, tratar de controlar el programador directamente es definitivamente un antipatrón; el dolor a menudo seguirá.

En cambio, piense más acerca de los goroutines como trozos de hardware digital en comunicación (las máquinas de estado son una buena analogía). Es mejor aprender sobre el modelo de Procesamiento Secuencial de Comunicaciones en el que se basan los goroutines. En un diseño basado en CSP, cada goroutine tiene su propio estado privado e intercambia mensajes para interactuar con el estado de otros goroutines. El paso de mensajes obliga a la sincronización, que el planificador usa para determinar qué actividad obtiene el tiempo de CPU y qué se pone en una cola de espera.

Cuando te acerques a Go de esta manera, probablemente nunca tengas que preocuparte por las partes internas del programador.

En el tutorial de GO, tenemos esta diapositiva: Goroutines

package main import ( "fmt" "time" ) func say(s string) { for i := 0; i < 5; i++ { time.Sleep(100 * time.Millisecond) fmt.Println(s) } } func main() { go say("world") say("hello") }

La ejecución de este código produce resultados esperados ("mundo" y "hola" escritos en la pantalla indistintamente 5 veces).

Sin embargo, si comentamos el time.Sleep . time.Sleep (y por lo tanto, la línea de "time" de la importación) y ejecutamos el programa nuevamente, nos queda solo "hola" escrito en la pantalla cinco veces.

¿Qué tiene de importante el time.Sleep ? ¿Duerme eso que evita que el goroutine se muera?


Si quita tiempo. Duerma de la función decir que el principal ejecutará decir ("hola") y terminará sin ejecutar el goroutine. Si agrega un tiempo. Duerma (o elija un {} ) antes del extremo principal, le dará tiempo a la rutina para que se ejecute y ese hilo se elegirá del planificador.

Ejemplo:

package main import ( "fmt" "time" ) func say(s string) { for i := 0; i < 5; i++ { // time.Sleep(100 * time.Millisecond) fmt.Println(s) } } func main() { go say("world") say("hello") time.Sleep(1*time.Second) // Vs: // select {} // blocks indefinitely, requires manual interrupt // In CSP-speak the empty select is like STOP. // for{} would cause the cpu to max and the process''s STATE will be `running` // select{} will not cause the cpu to max and the process state will be `sleeping` }

La salida generalmente será 5 hola seguido por 5 mundo, pero también podría llegar a imprimir uno del mundo antes del último hola

PRUÉBELO -> (http: //) goo.gl/K2v7H0


Si quita el time.Sleep . time.Sleep , no le da la oportunidad a correr el goroutine say("world") . El programador de goroutine no es preventivo. Tus goroutines tienen que ceder el control antes de que se ejecute otro goroutine. Una forma de renunciar al control es correr el time.Sleep . time.Sleep .

Si quita el time.Sleep de la función say entonces la gorutina primaria se ejecuta 5 veces sin ceder el control a la rutina secundaria y luego, cuando la rutina principal vuelve de say el programa sale porque no hay nada para mantener el programa vivo.