golang - 사용법 메모 복구


기능: 프로그램이 패닉을 보고하면 전체 프로그램이 중단됩니다. 실제 작업에서는 패닉이 보고되는 곳이 많이 있을 수 있습니다. 일단 패닉이 보고되면 전체 서비스가 중단되므로 매우 위험합니다. Golang은 예외를 잡기 위해 Recover() 함수를 참조하므로 패닉이 보고되더라도 계속 실행될 수 있습니다.

 일반적으로 다음과 같이 작성됩니다.

defer func() {
        if err := recover(); err !=nil {
            fmt.Println(err)
        }
    }()


범위:

recover() 只是针对当前函数和以及直接调用的函数可能产生的panic,
它无法处理其调用产生的其它协程的panic


 예를 들어:

      1. 다음 프로그램에서는 test2() 함수가 실행되면 패닉이 발생하고 프로그램이 즉시 중단됩니다.

package main
 
import (
    "fmt"
)
 
 
func main() {
    test1()       //输出:this is test 1
    test2()       //输出:this is test 2  panic: test 2 is panic   直接挂掉
    test3()                 
}
 
func test1 (){
    fmt.Println("this is test 1")
}
 
func test2 (){
    fmt.Println("this is test 2")
    panic("test 2 is panic")
}
 
func test3 (){
    fmt.Println("this is test 3")
}


 
 
     2. test2() 함수에 복구()를 추가하면 프로그램은 test2() 함수까지 실행되며 패닉 오류가 발생하지 않고 프로그램은 계속해서 test()3 함수를 실행합니다.

package main
 
import (
    "fmt"
)
 
 
func main() {
    test1()   //输出:this is test 1
    test2()   //输出:this is test 2  test 2 is  panic
    test3()   //输出:this is test 3
}
 
func test1 (){
    fmt.Println("this is test 1")
}
 
func test2 (){
    defer func() {
        if err := recover(); err !=nil {
            fmt.Println(err)
        }
    }()
    fmt.Println("this is test 2")
    panic("test 2 is panic")
}
 
func test3 (){
    fmt.Println("this is test 3")
}


 
 
       3. 직접 호출되는 test2()의 메인 함수에 receive()를 넣으면 프로그램이 test2 함수를 실행할 때 패닉이 보고되는데 이때 test2() 프로그램이 중단되어 프로그램이 실행되지 않는다. 계속 실행합니다. defer에서 Recover() 함수를 직접 실행하면(또한 프로그램 어딘가에서 패닉 오류가 보고되더라도 결국 defer가 실행된다는 점에 유의하세요) 전체 프로그램이 중단되지 않습니다.

package main
 
import (
    "fmt"
)
 
 
func main() {
    defer func() {
        if err := recover(); err !=nil {
            fmt.Println(err)
        }
    }()
    test1()    //输出: this is test 1
    test2()    //输出: this is test 2; test 2 is panic
    test3()    //不会执行
}
 
func test1 (){
    fmt.Println("this is test 1")
}
 
func test2 (){
    fmt.Println("this is test 2")
    panic("test 2 is panic")
}
 
func test3 (){
    fmt.Println("this is test 3")
}


 
 
    4. test2()에 대해 go 코루틴이 열리면 프로그램은 여전히 ​​패닉 상태가 되어 전체 프로그램이 중단됩니다.

package main
 
import (
    "fmt"
)
 
 
func main() {
 
    defer func() {
        if err := recover(); err !=nil {
            fmt.Println(err)
        }
    }()
    
    test1()
    go test2()
    test3()
    for {
        select {
 
        }
    }
}
 
func test1 (){
    fmt.Println("this is test 1")
}
 
func test2 (){
    fmt.Println("this is test 2")
    panic("test 2 is panic")
}
 
func test3 (){
    fmt.Println("this is test 3")
}


 
 
  5. test2()에 대한 코루틴을 열 때 올바른 접근 방식은 전체 프로그램이 중단되지 않도록 이를 Recover()에 넣는 것입니다.

package main
 
import (
    "fmt"
)
 
 
func main() {
 
    test1()     // 输出:this is test 1
    go test2()  //  this is test 2; test 2 is panic
    test3()     //this is test3
    for {        //不推荐这样写 会造成死锁  此处只是单单为了 演示
        select {
 
        }
    }
}
 
func test1 (){
    fmt.Println("this is test 1")
}
 
func test2 (){
    defer func() {
        if err := recover(); err !=nil {
            fmt.Println(err)
        }
    }()
    fmt.Println("this is test 2")
    panic("test 2 is panic")
}
 
func test3 (){
    fmt.Println("this is test 3")
}


 
//출력 결과:

// this is test 1
// this is test 3
// this is test 2
// test is panic  


 

Guess you like

Origin blog.csdn.net/xuezhangjun0121/article/details/132762344