MST

星途 面试题库

面试题:Go语言panic与recover在并发场景下的处理

在Go语言的并发编程中,如果一个goroutine发生了panic,如何在其他goroutine中捕获并处理这个异常?请给出代码示例,并解释其中的原理。
20.5万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. 代码示例
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")
    }
}
  1. 原理解释
    • 在Go语言中,defer语句会在函数返回或发生panic时执行。通过在goroutine内部使用deferrecover来捕获本goroutine内发生的panic
    • recover函数用于在发生panic时恢复程序的正常执行,它只能在defer语句中有效。当goroutine发生panic时,defer语句中的recover函数会捕获到panic的值(如果有的话)。
    • 捕获到panic的值后,通过通道(chan)将这个值传递给其他goroutine。在主goroutine(或其他监听的goroutine)中,通过select语句监听这个通道,如果接收到值,就表示捕获到了goroutine内发生的panic,从而进行相应的处理。同时设置一个time.After的超时,以防止无限期等待。