- 代码示例:
package main
import (
"fmt"
"time"
)
func main() {
var panicChan = make(chan interface{})
go func() {
defer func() {
if p := recover(); p != nil {
panicChan <- p
}
}()
// 模拟一个会发生panic的操作
panic("goroutine panic")
}()
select {
case p := <-panicChan:
fmt.Printf("捕获到panic: %v\n", p)
case <-time.After(2 * time.Second):
fmt.Println("等待超时,未捕获到panic")
}
}
- 原理解释:
- 在Go语言中,
defer
语句会在函数返回或发生panic
时执行。通过在goroutine
内部使用defer
和recover
来捕获本goroutine
内发生的panic
。
recover
函数用于在发生panic
时恢复程序的正常执行,它只能在defer
语句中有效。当goroutine
发生panic
时,defer
语句中的recover
函数会捕获到panic
的值(如果有的话)。
- 捕获到
panic
的值后,通过通道(chan
)将这个值传递给其他goroutine
。在主goroutine
(或其他监听的goroutine
)中,通过select
语句监听这个通道,如果接收到值,就表示捕获到了goroutine
内发生的panic
,从而进行相应的处理。同时设置一个time.After
的超时,以防止无限期等待。