var wg sync.WaitGroup type Result struct { path string data [md5.Size]byte } func md5AllByWaitGroup(root string) (map[string][md5.Size]byte,error) { ctx,cancel := context.WithCancel(context.Background()) defer cancel() paths := make(chan string) wg.Add(1) go getPath(paths,root,ctx) ret := make(chan Result) for i :=0;i<20;i++{ wg.Add(1) go func(paths chan string,ret chan Result) { defer wg.Done() for path := range paths{ data,err := ioutil.ReadFile(path) if err !=nil{ return } select { case ret <- Result{path: path,data: md5.Sum(data)}: case <-ctx.Done(): return } } }(paths,ret) } go func() { wg.Wait() close(ret) }() m1 := make(map[string][md5.Size]byte) for v := range ret{ m1[v.path] = v.data } return m1,nil } func getPath(paths chan string,root string,ctx context.Context) { defer wg.Done() defer close(paths) filepath.Walk(root, func(path string, info os.FileInfo, err error) error { if err !=nil{ return err } if !info.Mode().IsRegular(){ return nil } select { case paths<- path: case <-ctx.Done(): return ctx.Err() } return nil }) } func WaitGroupDemo() { m,err := md5AllByWaitGroup(".") if err !=nil{ log.Fatal(err) } for k,sum := range m{ fmt.Printf("%s:\t %x\n",k,sum) } }
以上使用WaitGroup 实现
执行方式
结果:
func md5AllByErrGroup(ctx context.Context,root string) (map[string][md5.Size]byte,error) { g,ctx := errgroup.WithContext(ctx) paths := make(chan string) g.Go(func() error { defer close(paths) return filepath.Walk(root, func(path string, info os.FileInfo, err error) error { if err !=nil{ return err } if !info.Mode().IsRegular(){ return nil } select { case paths <-path: case <-ctx.Done(): return ctx.Err() } return nil }) }) c :=make(chan Result) for i:=0;i<20;i++{ g.Go(func() error { for path := range paths{ data,err := ioutil.ReadFile(path) if err !=nil{ return err } select { case c <- Result{path: path,data: md5.Sum(data)}: case <-ctx.Done(): return ctx.Err() } } return nil }) } go func() { g.Wait() close(c) }() m := make(map[string][md5.Size]byte) for v := range c{ m[v.path] = v.data } if err := g.Wait();err !=nil{ return nil,err } return m,nil } func ErrGroupDemo() { m,err := md5AllByErrGroup(context.Background(),".") if err !=nil{ log.Fatal(err) } for k,sum := range m{ fmt.Printf("%s:\t %x\n",k,sum) } }
以上是ErrGroup 实现,
执行方式
结果
原文:https://www.cnblogs.com/pebblecome/p/14311860.html