golang panic及处理机制

管理管理2022-11-25170 阅读0 评论

一 panic机制

  panic会将这个异常不断向上抛出,直到有地方处理它,如果有处理,则不会再向上抛出。倘若没有处理,那么最终会导致main挂掉.

 golang虽然没有try catch机制,却有一种类似的recover机制,后续demo我们可以观测到它的用法和作用

二 实例   

2.1 main用recover

func main() {
    defer func() {
        if err := recover(); err != nil {
            log.Println("err:", err)
        }
    }()
    go test1()
    time.Sleep(time.Second * 3)
    panic(errors.New("stop test1"))
    log.Println("123")
    select {}
}
func test1() {
    for {
        tm := time.NewTicker(time.Second)
        select {
        case <-tm.C:
            log.Println("test1")
        }
    }
}
golang panic及处理机制

2.2 func用recover

func main() {
    defer func() {
        if err := recover(); err != nil {
            log.Println("err:", err)
        }
    }()
    go test1()
    time.Sleep(time.Second * 3)
    makeerr()
    log.Println("123")
    select {}
}
 
func test1() {
    for {
        tm := time.NewTicker(time.Second)
        select {
        case <-tm.C:
            log.Println("test1")
        }
    }
}
func makeerr() {
    defer func() {
        if err := recover(); err != nil {
            log.Println("makeerr:", err)
        }
    }()
    panic(errors.New("stop"))
}
golang panic及处理机制

此时我们在func中用recover,那么挂掉的只是func,他不会抛到main中,所以main能继续运行,继而main开辟的go test1也能继续运行

2.3 func用recover且开创goroutine

func main() {
    defer func() {
        if err := recover(); err != nil {
            log.Println("err:", err)
        }
    }()
 
    time.Sleep(time.Second * 3)
    makeerr()
    log.Println("123")
    select {}
}
 
func test1() {
    for {
        tm := time.NewTicker(time.Second)
        select {
        case <-tm.C:
            log.Println("test1")
        }
    }
}
func makeerr() {
    defer func() {
        if err := recover(); err != nil {
            log.Println("makeerr err:", err)
        }
    }()
    go test1()
    panic(errors.New("stop test"))
}
golang panic及处理机制

我们发现,func虽然挂掉了,但是他开创的go没挂掉,因为即使是这个函数退出了,新开的协程是相当于基于main下的一个子程,只要main不退出,他依然会“存活”

2.4 goroutine中panic

func main() {
    defer func() {
        if err := recover(); err != nil {
            log.Println("err:", err)
        }
    }()
    go test1()
    time.Sleep(time.Second * 3)
    log.Println("123")
    select {}
}
func test1() {
    log.Println("test1 start")
    panic(errors.New("stop test1"))
    log.Println("test1 end")
}
golang panic及处理机制

协程中如果没recover,那么error就会抛向main,main就会挂掉,从而没有执行到后面的log打印。

---> 这种情况,main中做defer recover是没用的

2.5 func1内嵌func2中panic且func2做处理

func main() {
    test1()
    time.Sleep(time.Second * 3)
    log.Println("123")
}
func test1() {
    log.Println("test1 start")
    test2()
    log.Println("test1 end")
}
func test2() {
    defer func() {
        if err := recover(); err != nil {
            log.Println("test2 err:", err)
        }
    }()
    log.Println("test2 start")
    panic(errors.New("stop test2"))
    log.Println("test2 end")
}
golang panic及处理机制

2.6 func1内嵌func中panic且func1做处理

func main() {
    test1()
    time.Sleep(time.Second * 3)
    log.Println("123")
}
func test1() {
    defer func() {
        if err := recover(); err != nil {
            log.Println("test? err:", err)
        }
    }()
    log.Println("test1 start")
    test2()
    log.Println("test1 end")
}
func test2() {
    log.Println("test2 start")
    panic(errors.New("stop test2"))
    log.Println("test2 end")
}
golang panic及处理机制

func2异常,执行终止,向调用者func1抛出进而本身退出,func1得到异常,执行终止,本身退出时recover进行处理,从而保活了main

到此这篇关于golang panic及处理机制的文章就介绍到这了,更多相关golang panic内容请搜索M135模板网以前的文章或继续浏览下面的相关文章希望大家以后多多支持M135模板网!

The End 微信扫一扫

文章声明:以上内容(如有图片或视频在内)除非注明,否则均为模板汇原创文章,转载或复制请以超链接形式并注明出处。

本文作者:管理本文链接:https://baijiaci.com/news/2212.html

上一篇 下一篇

相关阅读

取消
微信二维码
微信二维码
支付宝二维码