Go 루틴을 적절하게 중지하는 방법: 교착 상태 및 응답하지 않는 프로세스를 방지하기 위한 가이드?

Linda Hamilton
풀어 주다: 2024-10-28 14:11:02
원래의
535명이 탐색했습니다.

 How to Gracefully Stop a Go Routine: A Guide to Avoiding Deadlocks and Unresponsive Processes?

Go 루틴을 우아하게 중지하는 방법

Go에서 고루틴은 가벼운 동시성을 제공하지만 우아하게 종료하는 것은 어려울 수 있습니다. 이 질문은 고루틴의 실행을 중지하기 위해 신호를 보내야 하는 필요성에 대해 설명합니다.

제공된 코드는 부울 플래그(tooLate)를 true로 설정하여 고루틴을 중지하려는 시도를 보여줍니다. 그러나 이 접근 방식은 채널에서 읽는 것이 고루틴을 차단하므로 문제가 있습니다.

해결책 1: 추가 채널 사용

해결책에는 두 번째 채널을 사용하는 것이 포함됩니다(너무 늦음). 정지 신호를 전달합니다. 이 채널은 고루틴이 적극적으로 읽지 않을 때에도 열려 있습니다.

<code class="go">func main() {
    tooLate := make(chan struct{}) // Unbuffered channel for stop signal
    proCh := make(chan string)

    go func() {
        for {
            fmt.Println("working")
            time.Sleep(1 * time.Second)
            select {
            case <-tooLate:
                fmt.Println("stopped")
                return
            case proCh <- "processed": // Non-blocking send
            default: // Allows the goroutine to continue without blocking
            }
            fmt.Println("done here")
        }
    }()

    select {
    case proc := <-proCh:
        fmt.Println(proc)
    case <-time.After(1 * time.Second):
        fmt.Println("too late")
        close(tooLate) // Signal to goroutine to stop
    }

    time.Sleep(4 * time.Second)
    fmt.Println("finish\n")
}</code>
로그인 후 복사

이 솔루션에서는 시간 제한이 만료되면 tooLate 채널이 닫혀서 고루틴이 차단 select 문을 종료하게 됩니다.

해결책 2: sync.Cond 사용

또는 sync.Cond 유형을 사용하여 보다 정교한 신호 메커니즘을 구현할 수 있습니다. 예는 다음과 같습니다.

<code class="go">func main() {
    var stopped bool
    cond := sync.NewCond(new(sync.Mutex))

    go func() {
        for {
            cond.L.Lock()
            defer cond.L.Unlock()

            if stopped {
                fmt.Println("stopped")
                return
            }
            fmt.Println("working")
            cond.Wait() // Wait for the signal to stop
        }
    }()

    time.Sleep(1 * time.Second)
    cond.Signal() // Send the stop signal

    time.Sleep(4 * time.Second)
    fmt.Println("finish\n")
}</code>
로그인 후 복사

이 접근 방식을 사용하면 goroutine은 cond.Signal()에서 신호를 받을 때까지 cond.Wait() 메서드를 기다립니다.

위 내용은 Go 루틴을 적절하게 중지하는 방법: 교착 상태 및 응답하지 않는 프로세스를 방지하기 위한 가이드?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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