本文介绍 conc - 一个更好的 go 并发库, sourcegraph 在日常开发中使用go原生并发出现了问题,由此开发了 conc ,相比标准并发代码更优雅,代码更少,下面展示一个例子,可以看出代码减少了许多.
typepropagatedPanicstruct{valanystack[]byte}funcmain(){done:=make(chan*propagatedPanic)gofunc(){deferfunc(){ifv:=recover();v!=nil{done<-&propagatedPanic{val:v,stack:debug.Stack(),}}else{done<-nil}}()doSomethingThatMightPanic()}()ifval:=<-done;val!=nil{panic(val)}}// conc
funcmain(){varwgconc.WaitGroupwg.Go(doSomethingThatMightPanic)// panics with a nice stacktrace
wg.Wait()}
funcmain(){p:=pool.New().WithMaxGoroutines(4).WithContext(context.Background()).WithCancelOnError()fori:=0;i<3;i++{i:=ip.Go(func(ctxcontext.Context)error{ifi==2{returnerrors.New("I will cancel all other tasks!")}<-ctx.Done()returnnil})}err:=p.Wait()fmt.Println(err)}
p:=pool.NewWithResults[int]()fori:=0;i<10;i++{i:=ip.Go(func()int{returni*2})}res:=p.Wait()// Result order is nondeterministic, so sort them first
sort.Ints(res)fmt.Println(res)
funcmain(){times:=[]int{20,52,16,45,4,80}stream:=stream2.New()for_,millis:=rangetimes{dur:=time.Duration(millis)*time.Millisecondstream.Go(func()stream2.Callback{time.Sleep(dur)// This will print in the order the tasks were submitted
returnfunc(){fmt.Println(dur)}})}stream.Wait()}