カテゴリ: Go言語 更新日: 2025/12/22

Go言語のタイムアウト処理をselect文で実現する方法を解説!初心者向け完全ガイド

Go言語のタイムアウト処理をselect文で実現する例
Go言語のタイムアウト処理をselect文で実現する例

先生と生徒の会話形式で理解しよう

生徒

「先生、Go言語で処理が終わらないときに、途中で止める方法ってありますか?」

先生

「とても良い質問ですね。Go言語では、select文を使って、一定時間が経ったら処理を中断する“タイムアウト処理”を実現できますよ。」

生徒

「タイムアウト処理って、たとえばネットの通信が遅いときに止めるみたいなやつですか?」

先生

「その通りです!たとえば外部APIにアクセスするときや、チャネルからのデータ受信が遅いときなどに、とても役立ちます。では、具体的な使い方を見ていきましょう。」

1. Go言語のselect文とは?

1. Go言語のselect文とは?
1. Go言語のselect文とは?

Go言語(Golang)におけるselect文は、複数のチャネル操作を同時に待つための構文です。
例えば、あるチャネルから値を受け取る処理と、タイムアウトを待つ処理を同時に監視することができます。
select文は、「どれか1つのチャネルが準備できた時点」で、そのケースを実行します。

この特性を利用すると、「一定時間待ってもデータが来なければ処理を中断する」といったタイムアウト処理が簡単に書けます。

2. time.Afterを使ったタイムアウト処理の基本

2. time.Afterを使ったタイムアウト処理の基本
2. time.Afterを使ったタイムアウト処理の基本

Go言語のtimeパッケージには、指定した時間が経過したら値を送信するチャネルを返すtime.After関数があります。これをselect文と組み合わせることで、簡単にタイムアウトを実装できます。

次のコードは、チャネルからデータを待ちつつ、3秒以内にデータが来なければタイムアウトする例です。


package main

import (
    "fmt"
    "time"
)

func main() {
    ch := make(chan string)

    // ゴルーチンで遅れて値を送信
    go func() {
        time.Sleep(5 * time.Second)
        ch <- "完了しました!"
    }()

    select {
    case msg := <-ch:
        fmt.Println("受信:", msg)
    case <-time.After(3 * time.Second):
        fmt.Println("タイムアウトしました!")
    }
}

上記のプログラムでは、5秒後に値を送信するゴルーチンと、3秒間だけ待つtime.Afterを同時に監視しています。3秒以内にデータが来なかったため、「タイムアウトしました!」と表示されます。

実行結果は次のようになります。


    タイムアウトしました!

3. select文の仕組みを理解しよう

3. select文の仕組みを理解しよう
3. select文の仕組みを理解しよう

select文の動作は、複数の「チャネル受信または送信ケース」を同時に待機し、最初に準備ができたものだけを実行します。
このため、time.Afterと他のチャネルを一緒に書くと、「データを受け取るか、一定時間でタイムアウトするか」の二択が自動的に実現されます。

もしデータの受信が完了すれば、msg := <-chの方が実行され、そうでなければ<-time.Afterの方が実行される仕組みです。

4. 実用的なタイムアウト処理の応用例

4. 実用的なタイムアウト処理の応用例
4. 実用的なタイムアウト処理の応用例

次に、実際の処理で使うような例を見てみましょう。たとえばAPI通信やデータベースのアクセスが遅い場合に、無限に待たないようにすることが大切です。


package main

import (
    "fmt"
    "time"
)

func fetchData(ch chan string) {
    // データ取得に時間がかかる処理(例: ネット通信)
    time.Sleep(2 * time.Second)
    ch <- "データ取得完了!"
}

func main() {
    ch := make(chan string)

    go fetchData(ch)

    select {
    case result := <-ch:
        fmt.Println(result)
    case <-time.After(1 * time.Second):
        fmt.Println("処理が遅いためタイムアウトしました")
    }
}

この例では、実際の処理が2秒かかるのに、待機時間を1秒に設定しています。そのため、先にtime.Afterが発火し、「処理が遅いためタイムアウトしました」と表示されます。


    処理が遅いためタイムアウトしました

もし逆に、待機時間を3秒にすれば、「データ取得完了!」と表示されます。状況に応じて、タイムアウト時間を調整するのがポイントです。

5. タイムアウト処理を使うメリット

5. タイムアウト処理を使うメリット
5. タイムアウト処理を使うメリット

プログラムが「止まったまま動かない」状態を防ぐためには、タイムアウト処理が非常に重要です。
特に、外部との通信(API、ファイル読み込み、ネットワーク処理など)は、相手の応答が遅い場合があります。タイムアウトを設けることで、エラー処理を適切に行い、アプリ全体の安定性を保つことができます。

  • 通信が途切れても無限に待たずに処理を中断できる
  • ユーザーに「再試行してください」とメッセージを出せる
  • プログラムがフリーズするのを防げる

Go言語を基礎からスッキリ学びたい人や、 文法だけでなく「実用的な使い方」まで押さえたい人には、 定番の入門書がこちらです。

基礎からわかるGo言語をAmazonで見る

※ Amazon広告リンク

6. select文とtime.Afterの注意点

6. select文とtime.Afterの注意点
6. select文とtime.Afterの注意点

便利なtime.Afterですが、毎回呼び出すと新しいタイマーが作られるため、大量に呼ぶ処理ではメモリを消費します。
繰り返しのタイムアウト処理が必要な場合は、time.NewTimerを使って再利用する方法もあります。


timer := time.NewTimer(3 * time.Second)
defer timer.Stop()

select {
case msg := <-ch:
    fmt.Println("受信:", msg)
case <-timer.C:
    fmt.Println("タイムアウト!")
}

このように、NewTimerを使えば、一度作ったタイマーを再利用でき、パフォーマンスの面でも効率的です。

関連セミナーのご案内

【超入門】ゼロから始めるGo言語プログラミング:最速で「動くアプリ」を作るマンツーマン指導

「プログラミングの仕組み」が根本からわかる。Go言語でバックエンド開発の第一歩を。

本講座を受講することで、単なる文法の暗記ではなく、「プログラムがコンピュータの中でどう動いているか」という本質的な理解につながります。シンプルながら強力なGo言語(Golang)を通じて、現代のバックエンドエンジニアに求められる基礎体力を最短距離で身につけます。

具体的な開発内容と環境

【つくるもの】
ターミナル(黒い画面)上で動作する「対話型計算プログラム」や、データを整理して表示する「ミニ・ツール」をゼロから作成します。自分の書いたコードが形になる感動を体験してください。

【開発環境】
プロの現場でシェアNo.1のVisual Studio Code (VS Code)を使用します。インストールから日本語化、Go言語用の拡張機能設定まで、現場基準の環境を一緒に構築します。

この60分で得られる3つの理解

1. 環境構築の完全な理解

「なぜ動くのか」という設定の仕組みを理解し、今後の独学で詰まらない土台を作ります。

2. Go言語の基本構造(変数・型)

データの種類やメモリの概念など、他言語にも通じるプログラミングの本質を学びます。

3. 読みやすいコードの書き方

ただ動くだけでなく、誰が見ても分かりやすい「綺麗なコード」を書くための考え方を伝授します。

※本講座は、将来的にバックエンドエンジニアクラウドインフラに興味がある未経験者のためのエントリー講座です。マンツーマン形式により、あなたの理解度に合わせて進行します。

セミナー画像

初めてのGo言語を一緒に学びましょう!

カテゴリの一覧へ
新着記事
New1
Swift
Swiftのnilとは?Optionalとの関係や初期化について初心者向けにやさしく解説!
New2
Go言語
Go言語のinit関数の役割と使い方!プログラム起動時の初期化処理
New3
Go言語
Go言語のマップの順序保証がない理由と扱い方の工夫をやさしく解説!初心者でもわかる基本知識
New4
Kotlin
Kotlinのforループの基本!範囲・配列・コレクションの繰り返し処理
人気記事
No.1
Java&Spring記事人気No1
Kotlin
Kotlinのsettings.gradleファイルを完全解説!初心者でもわかるプロジェクト設定の基本
No.2
Java&Spring記事人気No2
Go言語
Swiftの配列(Array)の使い方を完全ガイド!初心者でもわかるデータのまとめ方
No.3
Java&Spring記事人気No3
Go言語
Go言語のgo installコマンドの役割とインストール先の仕組みを徹底解説!
No.4
Java&Spring記事人気No4
Go言語
Swiftの文字列操作を完全ガイド!初心者でもわかるStringの基本
No.5
Java&Spring記事人気No5
Kotlin
KotlinのRoomで複雑なクエリを使いこなす!初心者でもわかる応用テクニック
No.6
Java&Spring記事人気No6
Swift
Swiftの高階関数map・filter・reduceを完全解説!初心者でもわかる配列操作の基本
No.7
Java&Spring記事人気No7
Go言語
Go言語のSQLインジェクション対策を完全解説!初心者でも安全なデータベース操作がわかる
No.8
Java&Spring記事人気No8
Go言語
Go言語のインストール方法まとめ!Windows・Mac・Linux別に手順を丁寧に解説