>백엔드 개발 >Golang >채널이 있는 Go Goroutine에서 시간 초과를 올바르게 구현하는 방법은 무엇입니까?

채널이 있는 Go Goroutine에서 시간 초과를 올바르게 구현하는 방법은 무엇입니까?

DDD
DDD원래의
2024-11-08 14:57:02301검색

How to Implement Timeouts Correctly in Go Goroutines with Channels?

Go에서 채널에 시간 제한 사용

고루틴과 채널은 Go에서 동시 프로그래밍을 위한 강력한 메커니즘을 제공합니다. 그러나 고루틴에서 시간 초과를 처리하는 것은 까다로울 수 있습니다.

고루틴과 시간 초과를 사용하여 URL 목록의 연결 가능성을 확인하려는 시나리오에서는 다음과 같은 경우에도 시간 초과가 실행되지 않는 상황이 있을 수 있습니다. 일부 URL에 연결할 수 없습니다.

제공된 코드를 분석해 보겠습니다.

func check(u string) bool {
    time.Sleep(4 * time.Second)
    return true
}

func IsReachable(urls []string) bool {
    ch := make(chan bool, 1)
    for _, url := range urls {
        go func(u string) {
            select {
            case ch <- check(u):
            case <-time.After(time.Second):
                ch <- false
            }
        }(url)
    }
    return <-ch
}

문제 검사 기능 내에 있습니다. 고루틴에서 time.Sleep을 사용하면 현재 고루틴이 일시 중지됩니다. 이 경우에는 검사 기능을 실행하는 고루틴입니다. 검사 기능이 일시 중지된 동안 외부 고루틴의 select 문은 계속 실행을 시도합니다.

이 경우 select 문의 두 분기(결과 또는 시간 초과 확인)는 4 이후에 실행 가능합니다. 수표가 반환되면 초입니다. 그러나 두 가지 모두 실행 가능하므로 런타임은 둘 중 하나를 실행하도록 선택할 수 있으며 결과적으로 항상 true를 반환할 수 있습니다.

이 문제를 해결하려면 다음과 같이 각 검사 기능에 대해 새 고루틴을 만들어야 합니다. 아래의 수정된 코드:

func check(u string, checked chan<- bool) {
    time.Sleep(4 * time.Second)
    checked <- true
}

func IsReachable(urls []string) bool {
    ch := make(chan bool, 1)
    for _, url := range urls {
        go func(u string) {
            checked := make(chan bool)
            go check(u, checked)
            select {
            case ret := <-checked:
                ch <- ret
            case <-time.After(time.Second):
                ch <- false
            }
        }(url)
    }
    return <-ch
}

이 경우 검사 기능은 별도의 고루틴에서 실행되어 외부 고루틴을 일시 중지하지 않고 시간 초과가 가능하도록 합니다. 올바르게 실행하세요.

위 내용은 채널이 있는 Go Goroutine에서 시간 초과를 올바르게 구현하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.