タイムアウトとTicker
selectとtime.After、time.Tickの利用
「タイムアウトとTicker」はCoddyKit上の無料Go Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはGo Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Go Academyコースには全4レッスンが含まれています。
タイムアウトが重要な理由
タイムアウトがないと、低速なチャネルを待機するゴルーチンが永久にブロックする可能性があります。time パッケージには、チャネル操作に時間ベースの制御を追加するための基本機能が用意されています。
1回限りのタイムアウトにtime.Afterを使う
time.After(d) は、期間 d が経過した後に値を受信するチャネルを返します。select のケースで使用して、待機を中断します。
select {
case res := <-ch:
fmt.Println(res)
case <-time.After(2 * time.Second):
fmt.Println("timed out")
}time.NewTimerによる繰り返しタイムアウト
再利用可能なタイマーには time.NewTimer を使用し、使用するたびに Reset を呼び出します。タイマーのリークを防ぐには Stop を呼び出します。
timer := time.NewTimer(5 * time.Second)
defer timer.Stop()
select {
case <-timer.C:
fmt.Println("timer fired")
}time.Tickとtime.NewTicker
time.Tick は便利ですが、内部の ticker をリークさせます。リソースを解放するために Stop() を呼び出せる time.NewTicker を優先してください。
ticker := time.NewTicker(500 * time.Millisecond)
defer ticker.Stop()
for range ticker.C {
fmt.Println("tick")
}ループ内のTicker
Ticker と done チャネルを組み合わせると、定期的な処理を実行し、正常に停止できます。
ticker := time.NewTicker(time.Second)
done := make(chan struct{})
go func() {
for {
select {
case <-ticker.C:
doWork()
case <-done:
ticker.Stop()
return
}
}
}()time.Afterによるリーク
time.After は呼び出すたびに新しいタイマーを作成し、そのタイマーが発火するまでガベージコレクションの対象になりません。密なループ内では、タイマーのリークを避けるために time.NewTimer と Reset を使用します。
デッドラインとタイムアウトの違い
タイムアウトは相対的な期間(「5秒待つ」)です。デッドラインは絶対時刻(「14:00まで待つ」)です。デッドラインを time.After 用の期間に変換するには、time.Until(deadline) を使用します。
deadline := time.Now().Add(5 * time.Second)
select {
case v := <-ch:
use(v)
case <-time.After(time.Until(deadline)):
fmt.Println("deadline exceeded")
}context.WithTimeoutを優先する
HTTP ハンドラーや構造化された処理では、単純なチャネルによるタイムアウトよりも context.WithTimeout を優先してください。呼び出しスタック全体にキャンセルを自動的に伝播できます。
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()Tickerによるレート制限
Ticker は最も単純なレートリミッターです。1回の tick につき1つのリクエストを送信します。バーストをサポートするには、バッファ付きチャネルをあらかじめ満たし、Ticker で補充します。
requests := make(chan int, 5)
for i := 0; i < 5; i++ { requests <- i }
close(requests)
limiter := time.NewTicker(200 * time.Millisecond)
for req := range requests {
<-limiter.C
fmt.Println("request", req)
}単調時計
Go のタイマー期間はウォールクロックではなく単調時計を使用するため、システム時刻の調整の影響を受けません。time.Since と time.Until も単調時計を使用します。
Tickerを正しく停止する
ticker.Stop() を呼び出しても、Ticker のチャネルは閉じられません。値の受信が停止するだけです。必要に応じて、戻る前にチャネルに残っている値を排出します。
確認問題
time.Tick よりも time.NewTicker が優先されるのはなぜですか?
復習: タイムアウトとTicker
重要なポイント:
- select での1回限りのタイムアウトには time.After を使用します
- 繰り返し処理には time.NewTicker を使用し、必ず Stop() を呼び出します
- ループ内での time.After は避けます。タイマーがリークするためです
- キャンセル可能な処理には context.WithTimeout を優先します
よくある質問
「タイムアウトとTicker」レッスンは無料ですか?
はい。「タイムアウトとTicker」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Go Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Go Academyコースには全4レッスンが含まれています。
「タイムアウトとTicker」で何を学びますか?
selectとtime.After、time.Tickの利用 ブラウザで直接実行するハンズオンコードでGo Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Go Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのGo Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「タイムアウトとTicker」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このGo Academyレッスンでコードを書いて実行できますか?
はい。すべてのGo Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- select文
- タイムアウトとTicker
- ファンインとファンアウトのパターン
- ワーカープールパターン