gpt4 book ai didi

go - Go 中的所有运行时错误都可以恢复吗?

转载 作者:IT王子 更新时间:2023-10-29 01:07:37 25 4
gpt4 key购买 nike

我认为一个等效的问题是 - 所有可能致命的运行时错误都会引起 panic 吗?因为任何引起 panic 的东西都应该是可以恢复的。我不是在谈论从诸如 os.Exit()log.Fatal() 之类的事情中恢复,也不是 Go 运行时中的错误,或者有人被电源绊倒cord,但会导致程序崩溃的其他运行时错误。

这是一个可以通过 panic/recover 捕获的运行时错误的示例:

package main

import (
"fmt"
)

func errorHandler() {
r := recover()
err := r.(error)
if err == nil {
return
}
fmt.Println(err.Error())
}

func foo() {
defer errorHandler()
smallSlice := []int{1, 0, 1}
smallSlice[10] = 1
}

func main() {
foo()
fmt.Println("recovery, end of main")
}

输出:

runtime error: index out of range
recovery, end of main

是否有运行时错误只会使程序崩溃而不会出现可恢复的 panic 的示例?

最佳答案

首先更改您的 errorHandler(),因为如果没有 panic ,r 将为 nil,因此类型断言将失败:

func errorHandler() {
if r := recover(); r != nil {
fmt.Println(r)
}
}

现在这里有一些示例代码会产生不可恢复的运行时错误:

1。内存不足:

func foo() {
defer errorHandler()
_ = make([]int64, 1<<40) // You have to change the size on 32-bit systems
}

2。并发映射写入和读取

有关详细信息,请参阅 How to recover from concurrent map writes? ,例如参见 Can marshalling a map[string]string to json return an error?

func foo() {
defer errorHandler()
m := map[string]int{}

go func() {
for {
m["x"] = 1
}
}()
for {
_ = m["x"]
}
}

3。栈内存耗尽

有关详细信息,请参阅 Does Go have an "infinite call stack" equivalent?

func foo() {
defer errorHandler()

var f func(a [1000]int64)
f = func(a [1000]int64) {
f(a)
}
f([1000]int64{})
}

4。尝试将 nil 函数作为 goroutine 启动

func foo() {
defer errorHandler()
var f func()
go f()
}

5。所有的 goroutines 都睡着了 - 死锁

标题说明了一切。下面是一个简单的代码来阻塞当前的 goroutine,但是如果你已经启动了其他的 goroutines,你显然不会遇到崩溃。在此处查看其他示例:Go project's main goroutine sleep forever?

func foo() {
defer errorHandler()
select {}
}

6。线程限制耗尽

如果您的 goroutines 被 IO 操作阻塞,可能会启动新线程来执行您的其他 goroutines。最大线程数显然有限制,如果达到,您的应用程序将崩溃。

关于go - Go 中的所有运行时错误都可以恢复吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57486620/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com