zoukankan      html  css  js  c++  java
  • golang panic及处理

    一 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")
            }
        }
    }

      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"))
    }

      此时我们在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"))
    }

     我们发现,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")
    }

     协程中如果没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")
    }

     

      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")
    }

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

  • 相关阅读:
    lsblk---列出所有可用块设备的信息,
    blkid---对系统块设备信息查询
    du---是对文件和目录磁盘使用的空间查看
    strings---对象文件或二进制文件中查找可打印的字符串
    which---查找并显示给定命令的绝对路径
    whereis---定位指令的二进制程序、源代码文件和man手册页等相关文件的路径。
    cd---切换工作目录
    cp---复制文件
    ls---显示文件目录各项信息
    pwd---以绝对路径的方式显示用户当前工作目录
  • 原文地址:https://www.cnblogs.com/bushuwei/p/15181582.html
Copyright © 2011-2022 走看看