2016-03-28 36 views
1

Akımları beklemek için aşağıdaki kodları kullanıyorum. beklenen çıktısı:Kanal almayı engelleme

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

Ama line5 sonra, benim kod asılı duruyor.

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

Her şeyi doğru yapıyorum. Bu asılı kodda hata ayıklamada bana yardımcı olabilir misiniz?

Teşekkürler!

cevap

1

Çünkü escape1 döngü için for scanner.Scan() döngüsünü sarar.

ben döngü için dış bunun benim için iyi çalıştığını kaldırın: 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

sayesinde! şimdi anladım. –