2016-05-31 9 views
0

Ich machte einige Bedingungsprüfung innerhalb der Goroutine basierend auf der sich wiederholenden Variable i und festgestellt, dass es mir Ergebnisse gibt, die ich nicht erwartet hatte, und ich beschloss, es mit einigen einfachen zu bestätigen Code.Iterieren mit einer Goroutine gibt unerwartetes Ergebnis

for i := 1; i <= 5; i++ { 
    wg.Add(1) 
    fmt.Println(i) 

    go func() { 
     fmt.Println(i) 
     wg.Done() 
    }() 


} 
wg.Wait() 

1 
2 
3 
4 
5 
6 
6 
6 
6 
6 

Ist dieses erwartete Verhalten? Könnte jemand freundlicherweise erklären, warum 6 für 5 Mal gedruckt wird, obwohl ich nur bis 5 ??

+1

Siehe auch die FAQ: https://golang.org/doc/faq#closures_and_goroutines – JimB

+0

Vielleicht ein genaueres Duplikat: http://stackoverflow.com/questions/36776315/go-concurrency-with-for-loop- und-anonymous-function-verhält sich-unerwartet – JimB

+0

Es ist nicht notwendig, dass Sie nur 6,6,6,6 erhalten. Erhöhe den Wert von i. Sie werden einen unterschiedlichen Wert erhalten. Sie erhalten den Wert von i zum Zeitpunkt der Ausführung der Goroutine. – khrm

Antwort

5

Playground example

Alle Ihre goroutines laufen asynchron nach Ihre for-Schleife beendet ist.

Am Ende Ihrer for-Schleife ist i gleich 6, und somit Ihre goroutines jedes Protokoll die Nummer 6.

das Problem beheben Sie einen Verschluss schaffen, und den aktuellen Wert von i innen speichern Wenn die goroutine ausgeführt wird, wird sie mit dem richtigen Wert i ausgeführt.

Um dies zu tun einfach Ihren Code ändern, so dass es wie

go func(x int) { 
    fmt.Println(x) 
    wg.Done() 
}(i) // <--- "save" value of i at this point in time. 

diese Weise können Sie „Speichern“, um den Wert von i in der Funktion, wie Sie sagen, die goroutine sieht, dass später auszuführen, wenn die für Schleife wurde bis zum Abschluss ausgeführt, es verwendet nicht aktuellen Wert von i, die 6 ist; Stattdessen verwendet es den alten Wert von i zum Zeitpunkt der Erstellung der Goroutine.