Golang のティッカー停止動作
Golang のティッカー パッケージを使用する場合、Stop() の動作とそれが与える影響を理解することが重要です。関連するチャンネルで。 Stop() の呼び出しはティッカーの送信を効果的に停止しますが、チャネルは閉じません。
次の例を考えてみましょう。
package main import ( "time" "log" ) func main() { ticker := time.NewTicker(1 * time.Second) go func(){ for _ = range ticker.C { log.Println("tick") } log.Println("stopped") }() time.Sleep(3 * time.Second) log.Println("stopping ticker") ticker.Stop() time.Sleep(3 * time.Second) }
このコードは、予期しない動作を示しています。ティッカー チャネルはticker.Stop()を使用して停止されますが、対応するゴルーチンはアクティブなままです。これにより、ゴルーチンの継続的な存在が望ましくないのかどうか、またそのような状況に対処する最善のアプローチについて懸念が生じます。
停止に 2 番目のチャネルを使用する
1 つの効果的な解決策は、以下を導入することです。 2 番目のチャネル、特にティッカーの停止信号を送信するためのものです。
package main import ( "log" "time" ) // Every runs the provided function periodically, allowing the function to control when to stop. func Every(duration time.Duration, work func(time.Time) bool) chan bool { ticker := time.NewTicker(duration) stop := make(chan bool, 1) // Channel for signaling stop go func() { defer log.Println("ticker stopped") for { select { case time := <-ticker.C: if !work(time) { // Function decides to stop stop <- true } case <-stop: // Signal to stop has been received return } } }() return stop } func main() { stop := Every(1*time.Second, func(time.Time) bool { log.Println("tick") return true }) time.Sleep(3 * time.Second) log.Println("stopping ticker") stop <- true // Send the stop signal on the stop channel time.Sleep(3 * time.Second) }
この変更されたコードでは、 Every() 関数は、期間と、続行するかどうかを示すブール値を返す関数の両方を受け取ります。停止チャネルは、停止信号をティッカーゴルーチンに伝達するために使用され、正常に終了することを保証します。
以上がGolang Ticker Goroutine を正常に終了するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。