2014-06-26 18 views
7

Ich lerne Go und ich wollte versuchen, goroutines und Kanäle.Warum wird meine Goroutine nicht ausgeführt?

Hier ist mein Code:

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!") 
} 

Und hier ist das Ergebnis:

Done! 

Ich verstehe nicht, warum meine goroutine nie ausgeführt wird. Die "Eingabe der Goroutine" wird nicht gedruckt und ich habe keine Fehlermeldung.

Antwort

15

Tatsache ist, dass Ihr goroutine beginnt, wird jedoch beendet, bevor irgendetwas zu tun, weil Ihr Programm direkt nach dem Druck stoppen Done!: Ausführung von goroutines ist unabhängig von dem Hauptprogramm, wird aber bei der gestoppt werden gleich wie das Programm. Also im Grunde brauchen Sie einen Prozess, um das Programm auf sie warten zu lassen. Es könnte ein anderer Kanal sein, der auf eine Anzahl von Nachrichten wartet, eine sync.WaitGroup oder andere Tricks.

Sie sollten die ausgezeichnete post about concurrency in go im Golang Blog lesen.

5

Ihre Goroutine hat nicht genug Zeit für die Ausführung, da die Hauptfunktion nach dem Drucken Done! beendet wird.

Sie müssen etwas tun, damit das Programm auf die Goroutine wartet.

Der einfachste Weg ist, eine time.Sleep() am Ende hinzuzufügen.

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!") 
} 

Eingabe der goroutine ...
ein
zwei
drei
Fertig!

Playground

Während dies funktioniert, ist es empfehlenswert, Kanäle zu verwenden, oder Funktionen aus dem sync Paket, zusätzlich zu goroutines, gleichzeitigen Code zu synchronisieren.

Beispiel:

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!") 
} 

die goroutine Eingabe ...
erhielt ein
erhielt zwei
erhielt drei
Fertig!

Playground

+1

Schlafen funktioniert, ist aber die schlechteste Lösung. In realen Situationen ist es nahezu nutzlos. – Elwinar

+0

@Elwinar, ja, aber es zeigt, warum das OP nicht sah, was sie erwartet hatten. – Intermernet

Verwandte Themen