関連記事
GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ
概要
以下、自分用のメモです。
周りから「time.Sleep()だとブロックしてしまうが、キャンセル出来るようにしたい」という話をちょこちょこ聞きます。
time.Sleep()
は、他の言語にもあるSleep関数と同様に現在のスレッド(ゴルーチン)を指定時間分ブロックしてしまいます。
キャンセル可能なスリープ処理を行いたい場合は、コンテキストとtime.Ticker
を利用するのが楽です。
サンプル
package times import ( "context" "time" "github.com/devlights/gomy/output" ) // CancellableSleep は、キャンセル可能なスリープ処理のサンプルです。 // // time.Sleep() は、ブロックしてしまうためキャンセル可能な状態で // スリープ処理を行いたい場合は、time.Tickerを利用して処理する。 // // # REFERENCES // - https://pkg.go.dev/time@go1.22.2#NewTicker func CancellableSleep() error { const ( timeFormat = time.TimeOnly + ".000" ) var ( ctx, cxl = context.WithTimeout(context.Background(), 3500*time.Millisecond) ticker = time.NewTimer(5 * time.Second) ) defer cxl() defer ticker.Stop() output.Stdoutl("[begin]", time.Now().Format(timeFormat)) defer func() { output.Stdoutl("[end ]", time.Now().Format(timeFormat)) }() // // 以下は5秒間スリープする処理があるとして、3.5秒でキャンセルします。 // time.Sleep(5 * time.Second) とすると 5秒間 ブロックされますが // context.Context と *time.Ticker.C を利用してselectで待機するようにしているため // 先に完了した方で抜けていきます。 // select { case <-ctx.Done(): output.Stdoutl("[cancel]", ctx.Err()) case <-ticker.C: output.Stdoutl("[sleep]", "done") } return nil }
try-golang/examples/basic/times/time_cancallable_sleep.go at main · devlights/try-golang · GitHub
実行すると以下のようになります。
$ task task: [build] go build . task: [run] ./try-golang -onetime ENTER EXAMPLE NAME: time_cancellable_sleep [Name] "time_cancellable_sleep" [begin] 07:33:29.449 [cancel] context deadline exceeded [end ] 07:33:32.951 [Elapsed] 3.502395005s
参考情報
https://pkg.go.dev/time@go1.22.1#Time.Format
https://x.com/func25/status/1776936187137229071
Goのおすすめ書籍
過去の記事については、以下のページからご参照下さい。
サンプルコードは、以下の場所で公開しています。