本文介绍: 在Go中,runtime包是负责处理Go运行时(runtime)的细节,包括垃圾回收协程调度等。当出现panic时,runtime包会负责处理这些异常情况。当程序出现panic异常传播:当一个函数发生panic时,该函数会立即停止执行,并将panic传播到调用它的函数这个过程会一直向上传播,直到被捕获程序终止。栈的展开(Unwinding):在panic发生时,Go运行时会开始展开调用栈(stack unwinding)。

在 Go 语言中,panicrecover 和 defer 是用于处理异常情况的关键字。它们通常一起使用实现程序错误处理恢复

1. defer 语句

defer 用于函数返回之前执行一段代码。被 defer 修饰语句函数会在包含 defer 的函数执行完毕后执行defer 常用资源清理、释放锁、关闭文件操作

func example() {
    defer fmt.Println("This will be executed last")
    fmt.Println("This will be executed first")
}

2. panic 和 recover

func example() {
    defer func() {
        if err := recover(); err != nil {
            fmt.Println("Recovered from panic:", err)
        }
    }()
 
    panic("This will cause a panic")
}

3. 示例

  1. 程序执行到 panic 语句时,它会立即停止当前函数执行,并开始沿调用堆栈向上执行所有的 defer 语句。
  2. 执行 defer 语句时,将其推迟的函数或语句加入一个栈中,但并不立即执行。
  3. 当所有的 defer 语句都被执行完毕后,程序终止当前函数执行,然后开始执行上一层函数的 defer 语句,以此类推。
  4. 如果在 defer 语句执行的过程中发生了 panic,则 panic 会被引发,但是在引发 panic 之前,会先执行该层级的 defer 语句。
  5. 如果有 recover 函数被调用,它会停止 panic 的传播,并返回传递给 panic 的值。

在 Go 中,一个协程goroutine出现 panic 不会直接影响其他协程的正常执行。Go 语言设计目标之一是实现轻量级并发,保持协程独立性。因此,一个协程的 panic 不会波及到其他协程

一个协程发生 panic 时,通常会触发系列的 defer 函数的执行,这提供了一种清理资源记录日志操作机制然后,Go 运行系统会停止当前协程的执行,但不会影响其他正在运行的协程。

其他协程会继续执行,而不受 panic 影响。这是由于 Go 使用处理异常机制,而不是像传统错误处理机制那样需要每个数中检查错误。在 Go 中,panic 主要用于表示程序遇到无法继续执行的错误情况。

下面是一个简单例子演示了一个协程的 panic 不会影响其他协程:

package main
 
import (
	"fmt"
	"sync"
	"time"
)
 
func main() {
	var wg sync.WaitGroup
 
	wg.Add(1)
	go func() {
		defer wg.Done()
		panicExample()
	}()
 
	// 启动另一个协程
	wg.Add(1)
	go func() {
		defer wg.Done()
		fmt.Println("Another goroutine is running.")
	}()
 
	// 等待所有协程结束
	wg.Wait()
}
 
func panicExample() {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("Recovered from panic:", r)
		}
	}()
 
	fmt.Println("Start of panicExample")
	time.Sleep(1 * time.Second)
	panic("Something went wrong!")
	fmt.Println("End of panicExample") // 不会执行到这里
}

这个例子中,panicExample 函数中的 panic 不会影响另一个协程的正常执行。虽然一个协程中发生了 panic,但其他协程仍然可以继续执行。

4. 总结

在Go中,runtime包是负责处理Go运行时(runtime)的细节,包括垃圾回收、协程调度等。当出现panic时,runtime包会负责处理这些异常情况。

程序出现panic时,Go运行时会按照以下步骤进行处理:

  1. 异常的传播:当一个函数发生panic时,该函数会立即停止执行,并将panic传播到调用它的函数。这个过程会一直向上传播,直到被捕获程序终止。
  2. 栈的展开(Unwinding):在panic发生时,Go运行时会开始展开调用栈(stack unwinding)。这意味着它会逆序执行当前调用栈中的函数,直到找到一个能够处理panic的函数。
  3. 恢复(Recovery):在展开调用栈的过程中,Go运行时会寻找一个适当的recover函数来捕获并处理panicrecover函数是在当前协程的上下文中执行的,用于捕获并处理当前协程中的panic。如果找到了一个recover函数,并且它成功处理了panic(即没有再次触发panic),则程序会从发生panic位置开始继续执行。
  4. 如果没有找到适当的recover函数来处理panic,程序将终止执行,并打印出相应的错误信息

在处理panic时,需要注意以下几点:

原文地址:https://blog.csdn.net/weixin_45925028/article/details/134546968

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_44058.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注