- 如果A发生panic,B会挂掉!(程序整体会panic)
- A协程的panic,只有A可以recover
func main() {
go func() {
for {
fmt.Println("goroutine A is ok")
time.Sleep(500 * time.Millisecond)
}
}()
go func() {
time.Sleep(1200 * time.Millisecond)
panic("goroutine B panic")
}()
time.Sleep(time.Second * 3)
}
goroutine A is ok
goroutine A is ok
goroutine A is ok
panic: goroutine B panic
goroutine 7 [running]:
main.main.func2()
/Users/bytedance/go/src/myself/test/main.go:18 +0x46
created by main.main
/Users/bytedance/go/src/myself/test/main.go:16 +0x4d
Process finished with the exit code 2
所以开启协程,要记得协程自己recover
func main() {
go func() {
defer func() {
if err := recover(); err != nil {
// 处理error
fmt.Println(err)
}
}()
//业务逻辑,如果发生panic,也会捕获
panic("panic in the goroutine")
}()
//其它协程
time.Sleep(time.Second)
}
结合上一篇errgroup,也要记得recover
func main() {
var eg errgroup.Group
for i := 0; i < 10; i++ {
i := i //这里要有局部变量,不然eg.Go()里面的i都是同一个数
eg.Go(func() error {
defer func() { //开协程先用defer来recover
if err := recover(); err != nil {
fmt.Println(err)
}
}()
time.Sleep(time.Second)
if i > 6 {
fmt.Println("error: ", i)
return fmt.Errorf("error: i = %d", i)
}
if i == 6 {
panic("panic at goroutine 6")
}
fmt.Println(i)
return nil
})
}
if err := eg.Wait(); err != nil { //err是errgroup遇到第一个error
log.Fatal(err)
}
}