2014-06-26 16 views
7

Sto imparando Go e volevo provare goroutine e canali.Perché la mia goroutine non è stata eseguita?

Ecco il mio codice:

package main 
import "fmt" 
func main(){ 

messages := make(chan string,3) 

messages <- "one" 
messages <- "two" 
messages <- "three" 

go func(m *chan string) { 
    fmt.Println("Entering the goroutine...") 
    for { 
     fmt.Println(<- *m) 
    } 
}(&messages) 

fmt.Println("Done!") 
} 

Ed ecco il risultato:

Done! 

Non capisco perché il mio goroutine non viene mai eseguito. La "Immissione della goroutine" non viene stampata e non ho alcun messaggio di errore.

risposta

15

Il fatto è che il goroutine inizia, ma è finito prima di fare qualsiasi cosa perché il programma si ferma subito dopo la stampa Done!: esecuzione di goroutines è indipendente del programma principale, ma verrà fermato al lo stesso del programma. Quindi, in pratica, hai bisogno di qualche processo per far sì che il programma li aspetti. Potrebbe essere un altro canale in attesa di un numero di messaggi, uno sync.WaitGroup o altri trucchi.

Si dovrebbe leggere l'eccellente post about concurrency in go nel blog golang.

5

La Goroutine non ha tempo sufficiente per l'esecuzione, poiché la funzione principale viene chiusa dopo la stampa Done!.

È necessario eseguire un'operazione per far attendere il programma alla Goroutine.

Il modo più semplice è aggiungere un time.Sleep() alla fine.

package main 

import (
    "fmt" 
    "time" 
) 

func main() { 

    messages := make(chan string, 3) 

    messages <- "one" 
    messages <- "two" 
    messages <- "three" 

    go func(m *chan string) { 
     fmt.Println("Entering the goroutine...") 
     for { 
      fmt.Println(<-*m) 
     } 
    }(&messages) 
    time.Sleep(5 * time.Second) 
    fmt.Println("Done!") 
} 

Entrando nel goroutine ...
uno
due
tre
Fatto!

Playground

Mentre questo funziona, si consiglia di utilizzare canali o funzioni dal pacchetto sync, oltre a goroutines, per sincronizzare il codice concorrente.

Esempio:

package main 

import (
    "fmt" 
) 

func main() { 

    messages := make(chan string, 3) 
    go func(m chan string) { 
     defer close(m) 
     fmt.Println("Entering the goroutine...") 
     messages <- "one" 
     messages <- "two" 
     messages <- "three" 
    }(messages) 
    for message := range messages { 
     fmt.Println("received", message) 
    } 
    fmt.Println("Done!") 
} 

Entrando nel goroutine ...
ricevuto uno
ricevuto due
ricevuto tre
Fatto!

Playground

+1

Dormire funziona, ma è la soluzione peggiore possibile. È quasi inutile in situazioni reali. – Elwinar

+0

@Elwinar, sì, ma dimostra perché l'OP non stava vedendo quello che si aspettavano. – Intermernet

Problemi correlati