golang の goroutine スケジューラがタイムアウトになった場合の対処方法
Go 言語において、Context パッケージを用いてゴルーチンのタイムアウト処理が行える。
まず、Context.Contextオブジェクトを作成して、タイムアウトを設定します。その次に、時間のかかる操作を実行するゴルーチンの中で、Context.WithTimeout関数を使用して、Contextオブジェクトをゴルーチンに渡します。ゴルーチンの内部では、select文を使用して、context.Done()チャネルのクローズイベントをリッスンします。そのチャネルがクローズされると、タイムアウトが発生したか、親ゴルーチンがキャンセルされたことを意味します。
以下、簡単なサンプルコードを示します。
package main
import (
"context"
"fmt"
"time"
)
func main() {
// 创建一个上下文对象,并设置超时时间为 1 秒
ctx, cancel := context.WithTimeout(context.Background(), time.Second*1)
defer cancel()
// 启动一个协程,并将上下文对象传递给协程
go doSomething(ctx)
// 等待 2 秒,以便协程有足够的时间执行
time.Sleep(time.Second * 2)
}
func doSomething(ctx context.Context) {
select {
case <-ctx.Done():
// 超时或者父级协程取消了
fmt.Println("Timeout or canceled")
return
default:
// 执行耗时操作
time.Sleep(time.Second * 3)
fmt.Println("Operation completed")
}
}
上記の例では、goroutineのdoSomethingは時間がかる操作を実行していますが、その際に設定されているタイムアウトは1秒です。1秒を超えると、context.Done()チャネルが閉じられ、selectステートメントのタイムアウトブランチが実行されて「Timeout or canceled」が出力されます。
実際の利用においては、具体的な業務シーンや要件に合わせてタイムアウト処理の方法を調整する必要があることにご注意ください。