Go在协程中正确捕获pinic
- 后端笔记
- 2024-02-02
- 602热度
- 0评论
众所周知,在golang中拆改使用go关键字即可快捷的开启一个异步协程,例如:
package main
func main() {
go hello()
}
func hello() {
println("Hello, World!")
}
那么一般我们捕获程序异常(pinic)是在调用前使用defer捕获异常后进行操作
package main
import "errors"
func main() {
defer func() {
if err := recover(); err != nil {
// 这里可以进行日志记录等操作
println(err.(error).Error())
}
}()
hello()
println("bye!")
select {}
}
func hello() {
println("Hello, World!")
panic(errors.New("hello panic"))
}
但是一旦在协程中pinic则main方法的defer将失去作用,比如将以上代码的hello调用前加上go关键字。
会发现整个程序都将停止运行,所以我们需要在会用到协程的方法内使用defer捕获协程内可能出现的pinic:
package main
import (
"errors"
"time"
)
func main() {
defer func() {
if err := recover(); err != nil {
// 这里可以进行日志记录等操作
println(err.(error).Error())
}
}()
go hello()
println("bye!")
select {}
}
func hello() {
defer func() {
if err := recover(); err != nil {
// 这里可以进行日志记录等操作
println("协程内异常:" + err.(error).Error())
}
// 延迟1秒重启
time.Sleep(time.Second)
go hello()
}()
println("Hello, World!")
panic(errors.New("hello panic"))
}