왜 `recover()`가 Go 루틴에서 패닉을 처리하지 못합니까?

Susan Sarandon
풀어 주다: 2024-11-06 20:01:03
원래의
878명이 탐색했습니다.

Why Does `recover()` Fail to Handle Panics in Go Routines?

Go 루틴의 패닉 처리

Go 루틴은 Go 프로그램에서 동시성을 제공하지만 이러한 루틴 내의 패닉은 문제를 일으킬 수 있습니다. 패닉을 복구하기 위해 일반적으로 Recover() 함수가 사용됩니다. 그러나 고루틴 내에서 복구()가 예상대로 작동하지 않는 경우가 있습니다.

Go 루틴의 복구 실패 이해

다음 코드 블록을 고려하세요.

func main() {
    done := make(chan int64)
    defer fmt.Println("Graceful End of program")
    defer func() {
     r := recover()
     if _, ok := r.(error); ok {
        fmt.Println("Recovered")
     }
    }()

    go handle(done)
    for {
        select{
        case <- done:
        return
        }
    } 
}

func handle(done chan int64) {
    var a *int64
    a = nil

    fmt.Println(*a)
    done <- *a
}
로그인 후 복사

이 코드는 main 함수의 deferred 함수를 사용하여 고루틴의 패닉에서 복구를 시도합니다. 그러나 패닉을 회복하는 데 실패합니다. 반대로 다음 코드 블록은 예상대로 작동합니다.

func main() {
    done := make(chan int64)
    defer fmt.Println("Graceful End of program")
    defer func() {
     r := recover()
     if _, ok := r.(error); ok {
        fmt.Println("Recovered")
     }
    }()

    handle(done)
    for {
        select{
        case <- done:
        return
        }
    } 
}

func handle(done chan int64) {
    var a *int64
    a = nil

    fmt.Println(*a)
    done <- *a
}
로그인 후 복사

복구 문제 해결

이 동작을 이해하는 열쇠는 고루틴의 특성에 있습니다. Recover()는 호출된 동일한 고루틴 내에서 발생하는 패닉에서만 복구할 수 있습니다. Go 블로그에서:

현재 고루틴의 모든 함수가 반환될 때까지 프로세스가 스택 위로 계속 진행되며, 이 시점에서 프로그램이 충돌합니다.

고루틴에서 패닉을 처리하려면 다음을 사용해야 합니다. 고루틴 자체 내에서 복구 기능 지연.

func handle(done chan int64) {
    defer func() {
        if r := recover(); r != nil {
            if _, ok := r.(error); ok {
                fmt.Println("Recovered in goroutine")
            }
        }
    }()

    var a *int64
    a = nil

    fmt.Println(*a)
    done <- *a
}
로그인 후 복사

복구 기능을 고루틴 내에 배치하면 패닉을 차단하고 적절하게 처리할 수 있습니다.

위 내용은 왜 `recover()`가 Go 루틴에서 패닉을 처리하지 못합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿