> 백엔드 개발 > Golang > Go에서 채널을 사용하여 Goroutine 시간 초과를 안정적으로 재정의하려면 어떻게 해야 합니까?

Go에서 채널을 사용하여 Goroutine 시간 초과를 안정적으로 재정의하려면 어떻게 해야 합니까?

Susan Sarandon
풀어 주다: 2024-12-14 20:56:21
원래의
216명이 탐색했습니다.

How Can I Reliably Override Goroutine Timeouts Using Channels in Go?

채널이 있는 고루틴의 시간 초과 무시

Golang에서는 비동기 작업에 고루틴과 채널을 사용할 때 다음을 보장하기 위해 시간 초과를 지정할 수 있습니다. 작업이 무기한 중단되지는 않습니다. 그러나 특정 시나리오에서는 시간 초과 사례가 예상대로 실행되지 않을 수 있습니다.

다음 코드 조각을 고려하세요.

package main

import (
    "fmt"
    "time"
)

func main() {
    c1 := make(chan int, 1) // Buffered channel with capacity 1

    go func() {
        for {
            time.Sleep(1500 * time.Millisecond) // Sleep for 1.5 seconds
            c1 <- 10 // Send value to channel
        }
    }()

    go func() {
        for {
            select {
            case i := <-c1:
                fmt.Println(i)
            case <-time.After(2000 * time.Millisecond):
                fmt.Println("TIMEOUT") // Not executed
            }
        }
    }()

    fmt.Scanln() // Wait for user input
}
로그인 후 복사

이 코드에는 두 개의 고루틴이 있습니다. 버퍼링된 채널 c1에 대한 값과 2초의 시간 초과로 c1에서 선택하는 다른 값입니다. 그러나 시간 초과 사례("TIMEOUT")는 인쇄되지 않습니다.

그 이유는 버퍼링된 채널의 특성과 시간 초과가 처리되는 방식에 있습니다. 이 시나리오에서 c1에 값을 보내는 goroutine은 1.5초마다 채널을 계속해서 다시 채웁니다. 결과적으로 두 번째 고루틴의 select 문은 시간 초과가 만료되기 전에 항상 c1에서 값을 받습니다.

이 문제를 해결하고 시간 초과 사례가 실행되도록 하려면 외부에서 시간 초과 채널을 만들어야 합니다. 선택 루프. 이렇게 하면 c1에서 값이 수신될 때마다 해당 값이 삭제되는 것을 방지할 수 있습니다.

timeout := time.After(2000 * time.Millisecond) // Create timeout channel only once
for {
    select {
    case i := <-c1:
        fmt.Println(i)
    case <-timeout:
        fmt.Println("TIMEOUT")
    }
}
로그인 후 복사

이 수정을 사용하면 select 문은 c1에서 계속 선택하지만 지정된 제한 시간 내에 값이 수신되지 않으면 "TIMEOUT" 케이스가 실행됩니다.

위 내용은 Go에서 채널을 사용하여 Goroutine 시간 초과를 안정적으로 재정의하려면 어떻게 해야 합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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