* Unknown User <knowsuperunkn...@gmail.com> [160920 06:43]: > Hi All, > > I am trying to print the contents of a file randomizing the lines. > The following code works, but does not exit even after all the lines are > read. > What needs to be done to correct it?
Try this <https://play.golang.org/p/Vg6f0gSs3l> package main import( "fmt" "bufio" "os" "math/rand" "sync" "time" ) func main() { filename := os.Args[1] if filename == "" { panic("No filename") } fh,err := os.Open(filename) if err != nil { panic(err) } scanner := bufio.NewScanner(fh) c := make(chan string) var wg sync.WaitGroup for scanner.Scan() { line := scanner.Text() wg.Add(1) go func(l string){ time.Sleep(time.Duration(rand.Intn(30)) * time.Millisecond) c <- l wg.Done() }(line) } go func() { wg.Wait() close(c) }() for { myline, ok := <-c if !ok { return } fmt.Println(myline) } } You need a way to determine when all of the spawned goroutines have sent their line to the channel so you know when to exit the bottom for loop. A select doesn't help, because the goroutines are sending on the channel at random intervals, so the default case will cause a busy loop between sends, not just after all sends have completed. The WaitGroup keeps track of how many worker goroutines have not yet finished. The final goroutine (started below the top for loop) waits for all the workers to finish, then closes the channel. The bottom for loop does not use a select statement; it merely reads from the channel, which will block until the next worker sends its line. When the final goroutine closes the channel, the channel read will return "", false, and the bottom for loop will exit. As a general rule of thumb, use a select only when you have more than one channel send and/or receive that you want to wait for, and only use a default case when you have other work that can be done if the channel operations are all blocked (waiting). Don't use default in an otherwise empty for loop around a select. hth...Marvin -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.