0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Golang における context とは?

Posted at

Go言語の Context パッケージ徹底解説

Go 言語の context パッケージは、ゴルーチン間でのキャンセル、タイムアウト、デッドライン、および値の共有を管理するための仕組みを提供します。本記事では、context パッケージの基本概念から具体的な使用方法まで詳しく解説します。


1. Context とは?

context は、Go 言語において非同期処理やネットワークリクエストの制御を容易にするための仕組みです。具体的には、以下の機能を提供します。

  • キャンセルの伝播: 特定の処理を中断するための仕組み
  • タイムアウト制御: 一定時間が経過したら処理を強制終了
  • デッドライン設定: 期限を指定して処理を中止
  • 値の受け渡し: ゴルーチン間でのデータ共有

Go の標準ライブラリの多くは context をサポートしており、HTTP リクエストやデータベースアクセスなどの処理を適切に管理できます。


2. context パッケージの基本的な使い方

context パッケージには、複数の関数が用意されており、それぞれ異なる用途で使用されます。

2.1 context.Background() の利用

context.Background() は、親となるコンテキストがない場合に使用される基本的なコンテキストです。

package main

import (
	"context"
	"fmt"
)

func main() {
	ctx := context.Background()
	fmt.Println(ctx)
}

2.2 context.WithCancel() でキャンセル処理

WithCancel を使うことで、キャンセルが可能なコンテキストを生成できます。

package main

import (
	"context"
	"fmt"
	"time"
)

func main() {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel() // 必ずキャンセルを呼び出す

	go func() {
		time.Sleep(2 * time.Second)
		cancel()
	}()

	<-ctx.Done()
	fmt.Println("Context canceled")
}

2.3 context.WithTimeout() でタイムアウト設定

一定時間後にキャンセルされるコンテキストを作成するには context.WithTimeout() を使用します。

package main

import (
	"context"
	"fmt"
	"time"
)

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
	defer cancel()

	select {
	case <-ctx.Done():
		fmt.Println("Timeout exceeded")
	}
}

2.4 context.WithDeadline() でデッドライン設定

特定の時刻をデッドラインとして設定する場合は context.WithDeadline() を使用します。

package main

import (
	"context"
	"fmt"
	"time"
)

func main() {
	deadline := time.Now().Add(3 * time.Second)
	ctx, cancel := context.WithDeadline(context.Background(), deadline)
	defer cancel()

	select {
	case <-ctx.Done():
		fmt.Println("Deadline reached:", ctx.Err())
	}
}

2.5 context.WithValue() で値を共有

context.WithValue() を使うと、コンテキスト内に値を保存してゴルーチン間で共有できます。

package main

import (
	"context"
	"fmt"
)

func main() {
	ctx := context.WithValue(context.Background(), "userID", 42)
	fmt.Println("User ID:", ctx.Value("userID"))
}

ただし、大きなデータを context に格納するのは推奨されていません。データ共有には context ではなく、チャネルや構造体を利用するのが適切です。


3. context を使うべき場面

context は以下のようなケースで特に有効です。

  • HTTP リクエストのタイムアウト管理
  • データベースクエリのキャンセル処理
  • 長時間実行される処理の制御
  • 複数のゴルーチン間での情報共有

まとめ

Go 言語の context パッケージを活用することで、非同期処理やゴルーチンの適切な管理が可能になります。特に、

  • context.Background() は基本となるコンテキスト
  • context.WithCancel() でキャンセル可能なコンテキストを作成
  • context.WithTimeout() で一定時間後にキャンセル
  • context.WithDeadline() で特定の時刻にキャンセル
  • context.WithValue() で値をゴルーチン間で共有

といった機能を理解し、適切に活用しましょう。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?