0Pricing
Go Academy · レッスン

タイムアウトと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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. select文
  2. タイムアウトとTicker
  3. ファンインとファンアウトのパターン
  4. ワーカープールパターン
← Go Academyに戻る