概要
Go 1.16 のリリース自体については以下の記事を参照ください。
Go 1.16 で signal パッケージに NotifyContext という関数が追加されました。
context.Context を受け取れるようになっているので、少し便利になりましたね。
サンプル作るほどでも無いと思いますが、一応自分用にメモメモ。
サンプル
signal.Notify
以前から存在している signal.Notify
関数を使ったサンプル
package signals import ( "context" "os" "os/signal" "time" "github.com/devlights/gomy/output" ) // Notify は、 signal.Notify のサンプルです. // // REFERENCES: // - https://golang.org/pkg/os/signal/#example_Notify func Notify() error { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 5*time.Second) ) defer mainCxl() defer procCxl() sigCh := make(chan os.Signal, 1) signal.Notify(sigCh, os.Interrupt) defer close(sigCh) select { case <-procCtx.Done(): output.Stdoutl("[Timeout]", "procCtx.Done()") case <-sigCh: output.Stdoutl("[Interrupt]", "Ctrl-C") } return nil }
実行すると以下のようになります。
何もせずに5秒経過した場合
gitpod /workspace/try-golang $ make run GO111MODULE=off go get golang.org/dl/go1.16 go1.16 download go1.16: already downloaded in /home/gitpod/sdk/go1.16 go1.16 run -race github.com/devlights/try-golang/cmd/trygolang -onetime -example "" ENTER EXAMPLE NAME: signal_notify [Name] "signal_notify" [Timeout] procCtx.Done() [Elapsed] 5.023452884s
5秒以内にCtrl-Cで割り込み入れた場合
gitpod /workspace/try-golang $ make run GO111MODULE=off go get golang.org/dl/go1.16 go1.16 download go1.16: already downloaded in /home/gitpod/sdk/go1.16 go1.16 run -race github.com/devlights/try-golang/cmd/trygolang -onetime -example "" ENTER EXAMPLE NAME: signal_notify [Name] "signal_notify" ^C[Interrupt] Ctrl-C [Elapsed] 2.790585428s
signal.NotifyContext
こちらが Go 1.16 で新たに追加された関数です。
package signals import ( "context" "os" "os/signal" "time" "github.com/devlights/gomy/output" ) // NotifyContext は、 Go 1.16 から追加された signal.NotifyContext のサンプルです. // // REFERENCES: // - https://golang.org/pkg/os/signal/#NotifyContext func NotifyContext() error { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 5*time.Second) sigCtx, sigCxl = signal.NotifyContext(procCtx, os.Interrupt) ) defer mainCxl() defer procCxl() defer sigCxl() <-sigCtx.Done() sigCxl() switch sigCtx.Err() { case context.Canceled: output.Stdoutl("[Interrupt]", "Ctrl-C") case context.DeadlineExceeded: output.Stdoutl("[Timeout]", "procCtx.Done()") } return nil }
実行すると以下のようになります。
何もせずに5秒経過した場合
gitpod /workspace/try-golang $ make run GO111MODULE=off go get golang.org/dl/go1.16 go1.16 download go1.16: already downloaded in /home/gitpod/sdk/go1.16 go1.16 run -race github.com/devlights/try-golang/cmd/trygolang -onetime -example "" ENTER EXAMPLE NAME: signal_notify_context [Name] "signal_notify_context" [Timeout] procCtx.Done() [Elapsed] 5.021714981s
5秒以内にCtrl-Cで割り込み入れた場合
gitpod /workspace/try-golang $ make run GO111MODULE=off go get golang.org/dl/go1.16 go1.16 download go1.16: already downloaded in /home/gitpod/sdk/go1.16 go1.16 run -race github.com/devlights/try-golang/cmd/trygolang -onetime -example "" ENTER EXAMPLE NAME: signal_notify_context [Name] "signal_notify_context" ^C[Interrupt] Ctrl-C [Elapsed] 3.135518739s
参考情報
過去の記事については、以下のページからご参照下さい。
- いろいろ備忘録日記まとめ
サンプルコードは、以下の場所で公開しています。
- いろいろ備忘録日記サンプルソース置き場