// go run v5.go -- $PWD // go run -race v5.go -- /usr/bin package main import ( "bufio" "flag" "fmt" "os" "path/filepath" "sync" ) // START global OMIT type lcResult struct { lc int path string err error } var ( lcC chan *lcResult // HLchan wg sync.WaitGroup ) // END global OMIT func lineCount(path string) (int, error) { f, err := os.Open(path) if err != nil { return 0, err } defer f.Close() r := bufio.NewReader(f) var lc int for err == nil { _, err = r.ReadString('\n') if err == nil { lc++ } } return lc, nil } func visit(path string, fi os.FileInfo, err error) error { if err != nil { return err } if !fi.Mode().IsRegular() { return nil } // START visit OMIT wg.Add(1) go func() { lc, err := lineCount(path) lcC <- &lcResult{lc, path, err} // HLchan wg.Done() }() // END visit OMIT return nil } // START main OMIT func main() { lcC = make(chan *lcResult, 100) // HLchan flag.Parse() root := flag.Arg(0) err := filepath.Walk(root, visit) if err != nil { fmt.Errorf("%s", err) } go func() { wg.Wait(); close(lcC) }() // HLchan var globalLineCount int for lcr := range lcC { // HLchan if lcr.err != nil { fmt.Errorf("%s", lcr.err) err = lcr.err } globalLineCount += lcr.lc fmt.Printf("%d\t%s\n", lcr.lc, lcr.path) } // HLchan fmt.Printf("%d\ttotal\n", globalLineCount) if err != nil { os.Exit(1) } } // END main OMIT