contextの基本的な動作(@Golang)

contextは英語の意味は『文脈』ですが、プログラミングにおいては言語に関わらず使われる用語なので、おそらく他に適切な用語はなさそう。

その意味するところはAPI境界を超えて、スレッド間でも共有可能なオブジェクトを提供するといったところかと思います。contextはあたかも一つのスレッドのような動作をするように思います。

contextが一番使われるシーンはJavaでもありますがHttpRequestのようなネットワーク処理でタイムアウトやキャンセルが発生するようなケースに相性が良いから。

以下はcontextでcancel()処理とtimeout()処理、それに何らかの値(key/value pair)を設定してみたもの。

package main

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

func main() {
	ctx0 := context.Background()		// to initialize the context

	ctx1, cancel1 := context.WithCancel(ctx0)	// to generate cancel function "cancel1"

	ctx3 := context.WithValue(ctx1, "key1", 99)

	go func(ctx1 context.Context) {
		select {
		case <-ctx1.Done():
			fmt.Println("th1 was canceled")
		}
	}(ctx1)

	ctx2, _ := context.WithTimeout(ctx0, 2*time.Second)	// to set the context to timeout mode

	go func(ctx2 context.Context) {
		select {
		case <-ctx2.Done():
			fmt.Println("th2 was timeouted", "key value : ", ctx3.Value("key1"))
		}
	}(ctx2)

	cancel1()

	time.Sleep(3*time.Second)
}

最後の3秒待ちは値が2秒だとfunc(ctx2)処理が完了する前にプログラムが終了するのでこの値以上が必要です。

channelを使ってclose()処理をしても同じように処理はできますが、

https://zenn.dev/hsaki/books/golang-context/viewer/done

じゃなぜcontextを使うかというと、channelはgoroutine限定ですがcontextは汎用的に使えるからと言うことになるでしょう。

 

admin