2016-04-20 3 views
1

im nächsten Beispiel sehen können, ich verstehe nicht, warum Wert Ende nicht, wenn, warum ich nicht ausgegeben, wenn Wert empfangen durch den Kanal

package main 

import "fmt" 

func main() { 
    start := make(chan int) 
    end := make(chan int) 

    go func() { 
     fmt.Println("Start") 
     fmt.Println(<-start) 
    }() 

    go func() { 
     fmt.Println("End") 
     fmt.Println(<-end) 
    }() 

    start <- 1 
    end <- 2 
} 

erhielt gedruckt Ich weiß sync.WaitGroup dieses Problem lösen können.

Antwort

1

Da das Programm beendet wird, wenn es das Ende von func main erreicht, unabhängig davon, ob andere goroutines ausgeführt werden. Sobald die zweite Funktion vom Kanal end empfangen wird, wird der Sendevorgang des Hauptsenders auf diesem Kanal entsperrt und das Programm wird beendet, bevor der empfangene Wert eine Chance erhält, an Println übergeben zu werden.

0

Der Endwert wird, denn sobald die main goroutine (die main Funktion ist eigentlich ein goroutine) beendet ist nicht gedruckt (in anderen Worten unblockierten erhalten) die andere Nicht-Haupt-goroutines hat nicht die Möglichkeit, abgeschlossen werden.

Wenn die Funktion main() zurückkehrt, wird das Programm beendet. Außerdem sind goroutines unabhängige Einheiten der Ausführung und wenn eine Anzahl von ihnen nacheinander beginnt, können Sie nicht darauf verlassen, wann eine goroutine tatsächlich gestartet wird. Die Logik Ihres Codes muss unabhängig von der Reihenfolge sein, in der goroutines aufgerufen wird.

Ein Weg, um Ihr Problem zu lösen (und das einfachste in Ihrem Fall) ist eine time.Sleep am Ende Ihrer main() Funktion zu setzen.

time.Sleep(1e9) 

Dadurch wird gewährleistet, dass die Haupt goroutine nicht entsperren und muss die anderen goroutines eine Änderung ausgeführt werden.

package main 

import (
    "fmt" 
    "time" 
) 

func main() { 
    start := make(chan int) 
    end := make(chan int) 

    go func() { 
     fmt.Println("Start") 
     fmt.Println(<-start) 
    }() 

    go func() { 
     fmt.Println("End") 
     fmt.Println(<-end) 
    }() 

    start <- 1 
    end <- 2 

    time.Sleep(1e9) 
} 

Eine andere Lösung, wie Sie erwähnt haben, ist waitgroup zu verwenden.

0

Neben dem Schlafmodus, in dem Sie die Uhrzeit angeben müssen, können Sie waitgroup verwenden, um das Programm warten zu lassen, bis die Ausführung der Goroutine abgeschlossen ist.

package main 

import "fmt" 
import "sync" 

var wg sync.WaitGroup 

func main() { 
    start := make(chan int) 
    end := make(chan int) 

    wg.Add(2) 
    go func() { 
     defer wg.Done() 
     fmt.Println("Start") 
     fmt.Println(<-start) 
    }() 

    go func() { 
     defer wg.Done() 
     fmt.Println("End") 
     fmt.Println(<-end) 
    }() 

    start <- 1 
    end <- 2 
    wg.Wait() 
} 
Verwandte Themen