协程A的panic,协程B能捕获吗
不能,协程需要自己在内部捕获自己的panic,其他协程无法捕获
funcmain(){gofunc(){//goroutine协程deferfunc(){ife:=recover();e!=nil{//捕获该协程的panic111111fmt.Println("recover",e)}}()panic("0000000")fmt.Println("11111111")//无法打印,panic之后就终止了不再执行后续的逻辑}()deferfunc(){ife:=recover();e!=nil{//捕获main协程的panic222222fmt.Println("recover",e)}}()panic("222222")//mian协程的panicfmt.Println("33333")//panic之后就终止了不再执行后续的逻辑time.Sleep(2*time.Second)//保证运行gofunc协程}
一个协程内的recover能捕获多次panic吗
不能,一个recover只能捕获一次panic,一一对应
funcmain(){gofunc(){//goroutine协程deferfunc(){ife:=recover();e!=nil{//捕获该协程的panic111111fmt.Println("recover",e)}}()panic("0000000")panic("44444444")//该panic无法捕获fmt.Println("11111111")//无法打印,panic之后就终止了不再执行后续的逻辑}()}
如何合理的使用协程,recover ,panic
可以在项目中把使用协程的逻辑封装成函数,统一管理入口处理
funccallGoroutine(handlers...func()error)(errerror){varwgsync.WaitGroupfor_,f:=rangehandlers{wg.Add(1)//每个函数启动一个协程gofunc(handlerfunc()error){deferfunc(){//每个协程内部使用recover捕获可能在调用逻辑中发生的panicife:=recover();e!=nil{//日志记录失败信息,捕获panic,不影响其他协程跟主协程运行fmt.Println("recover",e)}deferwg.Done()}()//取第一个报错的handler调用逻辑,并最终向外返回e:=handler()iferr==nil&&e!=nil{err=e}}(f)}wg.Wait()return}funcmain(){userRpc:=func()error{panic("userRpcfail")returnnil}//调用逻辑2orderRpc:=func()error{panic("orderRpcfail")returnnil}err:=callGoroutine(userRpc,orderRpc)iferr!=nil{fmt.Println(err)}}
作者:chInvictus