>백엔드 개발 >Golang >Go의 `select` 문에서 컨텍스트 취소의 우선순위를 어떻게 지정할 수 있나요?

Go의 `select` 문에서 컨텍스트 취소의 우선순위를 어떻게 지정할 수 있나요?

Mary-Kate Olsen
Mary-Kate Olsen원래의
2024-12-08 11:45:11421검색

How Can I Prioritize Context Cancellation in Go's `select` Statement?

Go의 Select 문의 우선순위 제어

Go에서 select 문은 고루틴 간의 비동기 통신을 허용합니다. 그러나 케이스 블록의 평가 순서로 인해 예상치 못한 결과가 발생할 수 있습니다. 이 문제는 컨텍스트가 취소될 때 루틴을 즉시 종료하는 등 특정 사례의 처리 우선순위를 지정하려고 할 때 발생합니다.

다음 코드를 고려하세요.

func sendRegularHeartbeats(ctx context.Context) {
    for {
        select {
        case <-ctx.Done():
            return
        case <-time.After(1 * time.Second):
            sendHeartbeat()
        }
    }
}

문제:
이 코드의 의도는 ctx.Done() 사례 처리에 우선순위를 두는 것입니다. time.After() 케이스. 그러나 Go의 비결정적 평가 순서로 인해 time.After() 사례가 먼저 평가되어 컨텍스트가 취소된 경우에도 하트비트가 전송되는 경우가 있습니다.

해결책:
승인된 답변에서 제안된 솔루션은 ctx.Done()에 대한 비차단 검사와 함께 중첩된 select 문을 추가하는 것을 제안합니다. 그러나 하트비트가 전송될 확률이 여전히 높기 때문에 이 방법으로 문제가 완전히 해결되지는 않습니다.

더 효과적인 접근 방식은 기본 사례를 추가하여 ctx.Done() 사례 처리의 우선 순위를 지정하는 것입니다. 외부 select 문:

func sendRegularHeartbeats(ctx context.Context) {
    ticker := time.NewTicker(time.Second)
    defer ticker.Stop()

    for {
        select {
        case <-ctx.Done():
            return
        default:
        }

        select {
        case <-ctx.Done():
            return
        case <-ticker.C:
            sendHeartbeat()
        }
    }
}

이렇게 하면 ctx.Done() 사례가 외부 select 문에서 먼저 평가되어 더 높은 우선 순위가 부여됩니다. 컨텍스트가 취소되면 루틴이 즉시 반환되고 하트비트가 전송되지 않습니다. time.After() 케이스가 먼저 도착하면 외부 select 문의 기본 케이스로 인해 무시됩니다.

위 내용은 Go의 `select` 문에서 컨텍스트 취소의 우선순위를 어떻게 지정할 수 있나요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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