面试题答案
一键面试- 实现思路:
- 在每个Goroutine中使用
recover
来捕获panic
,这样可以避免panic
导致整个程序崩溃。 - 为了正确清理资源,可以使用
defer
语句。defer
会在函数返回或panic
发生时执行,因此可以在defer
中编写资源清理代码。 - 可以使用一个共享的状态变量(如
sync.Mutex
保护的布尔值)来标记某个Goroutine是否发生了panic
,其他Goroutine可以根据这个状态决定是否继续执行或进行相应的处理。
- 在每个Goroutine中使用
- 关键代码片段:
package main
import (
"fmt"
"sync"
)
var (
panicOccurred bool
mu sync.Mutex
)
func worker(id int, wg *sync.WaitGroup) {
defer wg.Done()
defer func() {
if r := recover(); r != nil {
mu.Lock()
panicOccurred = true
mu.Unlock()
fmt.Printf("Goroutine %d caught panic: %v\n", id, r)
}
}()
// 模拟任务
if id == 2 {
panic("Simulated panic in Goroutine 2")
}
fmt.Printf("Goroutine %d is working\n", id)
}
func main() {
var wg sync.WaitGroup
numWorkers := 3
for i := 1; i <= numWorkers; i++ {
wg.Add(1)
go worker(i, &wg)
}
wg.Wait()
if panicOccurred {
fmt.Println("A panic occurred, but other Goroutines continued.")
} else {
fmt.Println("No panic occurred.")
}
}
在上述代码中:
worker
函数使用defer
和recover
来捕获可能的panic
。panicOccurred
和mu
用于记录和保护是否发生panic
的状态。- 在
main
函数中,启动多个Goroutine并等待它们完成,然后根据panicOccurred
的值输出相应的信息。这样可以确保即使某个Goroutine发生panic
,其他Goroutine也能继续执行并正确清理资源。