2016-03-28 4 views
1

Ich habe den folgenden Code zum Warten auf Streams. Die erwartete Ausgabe lautet:Go-Blockierung von Empfangskanal

line1 
line2 
line3 
line4 
line5 
escape1 
scan done 
done.... 

Aber nach line5, mein Code hält hängen.

var lines = ` 
line1 
line2 
line3 
line4 
line5 
line6 
line7 
` 

func main() { 
    var (
     donec = make(chan struct{}) 
     stream = make(chan string, 5000) 
     exitc = make(chan struct{}) 
    ) 
    go func() { 
     scanner := bufio.NewScanner(strings.NewReader(lines)) 
    escape1: 
     for { 
      for scanner.Scan() { 
       select { 
       case <-donec: 
        fmt.Println("escape1") 
        close(stream) 
        break escape1 
       default: 
        stream <- scanner.Text() 
       } 
      } 
     } 
     close(exitc) 
     fmt.Println("scan done") 
     return 
    }() 

escape2: 
    for { 
     select { 
     case txt, ok := <-stream: 
      if !ok { 
       fmt.Println("stream closed!") 
      } 
      fmt.Println(txt) 
      if strings.Contains(txt, "line5") { 
       close(donec) 
       <-exitc 
       break escape2 
      } 
     } 
    } 
    fmt.Println("done....") 
} 

Ich denke, ich mache alles richtig. Könnte mir jemand helfen, diesen hängenden Code zu debuggen?

Danke!

Antwort

1

Ich denke, es ist, weil Ihre escape1 for Schleife die for scanner.Scan() Schleife umschließt.

Wenn ich, dass für Schleife Außen entfernen funktioniert es gut für mich: https://play.golang.org/p/NU3m3Deil7

func main() { 
    var (
     donec = make(chan struct{}) 
     stream = make(chan string, 5000) 
     exitc = make(chan struct{}) 
    ) 
    go func() { 
     scanner := bufio.NewScanner(strings.NewReader(lines)) 
    escape1: 
     for scanner.Scan() { 
      select { 
      case <-donec: 
       fmt.Println("escape1") 
       close(stream) 
       break escape1 
      default: 
       stream <- scanner.Text() 
      } 
     } 

     close(exitc) 
     fmt.Println("scan done") 
     return 
    }() 

escape2: 
    for { 
     select { 
     case txt, ok := <-stream: 
      if !ok { 
       fmt.Println("stream closed!") 
      } 
      fmt.Println(txt) 
      if strings.Contains(txt, "line5") { 
       close(donec) 
       <-exitc 
       break escape2 
      } 
     } 
    } 
    fmt.Println("done....") 
} 
+0

Dank! jetzt habe ich es verstanden. –