2016-03-31 12 views
1

Dies ist ähnlich wie go tutorial select statement, aber ich habe keine Antwort von diesem Beitrag erhalten. Also habe ich hier gefragt. Danke für die Antwort.warum Golang Select-Anweisung wählt nicht zufällig einen Fall

In http://tour.golang.org/concurrency/5, scheint es "case c < - x:" ist immer bereit, was bedeutet, dass dieser Fall Select Anweisung nicht blockieren wird.

Basierend auf dem Satz "A wählen Blöcke, bis einer seiner Fälle ausgeführt werden kann, dann führt es diesen Fall aus. Es wählt einen zufällig, wenn mehrere bereit sind.", Wenn "case < -quit:" auch bereit ist, Die Select-Anweisung sollte nach dem Zufallsprinzip aus "case c < - x:" und "case < -quit:" ausgewählt werden. Aber das Programm geht immer in den "case < -quit:" Fall.

Ich änderte auch den Auswahlblock, um wie folgt zu sein. Dann in den ersten 10 Schleifen, das Programm nach dem Zufallsprinzip drucken 1-6, aber das Programm beendet einmal (die 11. Ausgabe) der Quit-Kanal hat den Wert 0.

Meine Frage ist, dass, wenn die fertigen Fälle zufällig ausgewählt sind, warum ist die elfte Auswahl immer der quit-Fall?

select { 
    case c <- 1: 
     x, y = y, x+y 
    case c <- 2: 
     x, y = y, x+y 
    case c <- 3: 
     x, y = y, x+y 
    case c <- 4: 
     x, y = y, x+y 
    case c <- 5: 
     x, y = y, x+y 
    case c <- 6: 
     x, y = y, x+y 
    case <-quit: 
     fmt.Println("quit") 
     return 
    } 
+0

Aber 'c <- x' ist * nicht * bereit, im Beispiel, wenn' quit' ist (basierend auf dem Beispiel, mit dem Sie verknüpft haben). Benutzt du denselben Code von der Tour? – JimB

+0

@JimB Ich verstehe nur, dass der c-Kanal ungepuffert ist. Vielen Dank! – shiningdo

Antwort

3

Auf den Case-Anweisungen, werden Sie Werte c (z c <- 1), die blockiert, bis etwas Senden c als foo := <- c off liest. Wenn etwas in quit schreibt, trifft es den Fall, in dem <-quit an ist und aus der Auswahl zurückkehrt.

Aus diesem Beispiel

package main 

import (
    "fmt" 
    "time" 
) 

func main() { 
    c := make(chan int) 
    quit := make(chan struct{}) 

    go func(q chan<- struct{}) { 
     time.Sleep(5 * time.Second) 
     q <- struct{}{} 
    }(quit) 

    go func(ch chan<- int) { 
     var x int 
     for range time.Tick(1 * time.Second) { 
      c <- x 
      x++ 
     } 
    }(c) 

    for { 
     select { 
     case foo := <-c: 
      fmt.Println("Foo", foo) 
     case bar := <-c: 
      fmt.Println("Bar", bar) 
     case <-quit: 
      fmt.Println("quit") 
      return 
     } 
    } 
} 

Sie die Werte zufällig auf Ihrem Rechner ausgedruckt sehen können, wie:

$ go run foo.go 
Bar 0 
Bar 1 
Foo 2 
Bar 3 
quit 

$ go run foo.go 
Bar 0 
Foo 1 
Bar 2 
Bar 3 
quit 
+0

Danke. Dein erster Satz sollte der Grund sein. Aber das Beispiel scheint nicht der Grund zu sein. Ich änderte den Code zu 'gehen func (ch chan <- int) {var x int für { c <- x x ++ } } (c)' und 'für Bereich time.Tick (1 * Zeit. Zweitens) { select {'Sie können sehen, dass c <- x nicht blockiert ist. Für die ursprünglichen Codes verschiebe ich das q <-0 in eine andere Funktion 'gehe func (q chan <- int) { time.Sleep (2 * time.Second) q <- 0 } (quit)' und versuche es um <-c im Fall shiningdo

+0

Ich bin mir nicht sicher, ich folge, was Sie meinen, kümmern sich darum, Ihre Frage mit dem Code zu aktualisieren, von dem Sie sprechen? 'c <- x 'blockiert überall, nicht nur in select, es sei denn, etwas liest von' c 'ab, weil c ein ungepufferter Kanal ist http://play.golang.org/p/3BemJwJjTk –

+0

Es ist auch erwähnenswert, dass wenn Sie versuchen dies auf dem Spielplatz, Sie werden nicht viel Zufälligkeit sehen, da der Spielplatz selbst deterministisch ist. –

Verwandte Themen