Golang에서 티커 채널을 사용할 때 고루틴을 올바르게 종료하는 방법은 무엇입니까?

Patricia Arquette
풀어 주다: 2024-11-07 19:16:02
원래의
478명이 탐색했습니다.

How to Properly Terminate a Goroutine When Using a Ticker Channel in Golang?

Golang의 티커 채널 동작

티커 채널을 반복하고 Stop()을 호출하면 채널이 일시 중지되지만 닫히지는 않습니다. 이로 인해 고루틴이 무기한 활성 상태로 유지될 수 있습니다.

사례 예:

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

package main

import (
    "fmt"
    "time"
)

func main() {
    ticker := time.NewTicker(1 * time.Second)
    go func() {
        for _ = range ticker.C {
            fmt.Println("tick")
        }
    }()
    time.Sleep(3 * time.Second)
    fmt.Println("stopping ticker")
    ticker.Stop()
    time.Sleep(3 * time.Second)
}
로그인 후 복사

출력:

2013/07/22 14:26:53 tick
2013/07/22 14:26:54 tick
2013/07/22 14:26:55 tick
2013/07/22 14:26:55 stopping ticker
로그인 후 복사

보시다시피 티커를 중지했음에도 불구하고 채널이 닫혀 있지 않기 때문에 고루틴은 무한정 계속 반복됩니다.

해결책:

고루틴이 종료되도록 하는 한 가지 방법은 다음과 같이 두 번째 채널을 사용하는 것입니다.

package main

import (
    "fmt"
    "log"
    "time"
)

// Run the function every tick
// Return false from the func to stop the ticker
func Every(duration time.Duration, work func(time.Time) bool) chan bool {
    ticker := time.NewTicker(duration)
    stop := make(chan bool, 1)

    go func() {
        defer log.Println("ticker stopped")
        for {
            select {
            case time := <-ticker.C:
                if !work(time) {
                    stop <- true
                }
            case <-stop:
                return
            }
        }
    }()

    return stop
}

func main() {
    stop := Every(1*time.Second, func(time.Time) bool {
        fmt.Println("tick")
        return true
    })

    time.Sleep(3 * time.Second)
    fmt.Println("stopping ticker")
    stop <- true
    time.Sleep(3 * time.Second)
}
로그인 후 복사

이 코드에서:

  • Every 함수는 두 개의 채널을 생성합니다. 티커 채널과 중지 채널.
  • 고루틴은 두 채널을 모두 반복합니다.
  • 작업 함수가 false를 반환하면 중지 채널에 알림이 전달되어 고루틴이 종료됩니다.
  • Stop()이 호출되면 stop 채널에 메시지를 보내 고루틴을 종료합니다.

위 내용은 Golang에서 티커 채널을 사용할 때 고루틴을 올바르게 종료하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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