関連記事
GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ
概要
以下、自分用のメモです。大した内容じゃないのですが、たまに聞かれるのでここにメモしておきます。
たまにですが、何もせずにただただジーッとしてるだけのプログラムが欲しいときがあります。特定のプロセスの存在を判定して何かをするプログラムがあったりする場合とか。
そういうときに以下のように
package main func main() { c := make(chan struct{}) <-c }
としてしまうかもしれませんが、これは動作しません。
$ go run . fatal error: all goroutines are asleep - deadlock! goroutine 1 [chan receive]: main.main() /home/dev/app/main.go:5 +0x25 exit status 2
まあ、そりゃそうですね。
なので、以下のようにする人が結構います。
package main import "time" func main() { for { time.Sleep(1 * time.Second) } }
これでも目的は果たせるのですが、無限にsleepでループしているのがちょっと無駄ってなります。不要なシステムコール(約1秒毎)が定期的に発行され、ほんの僅かですがCPUも消費しちゃう。
こういうときは、素直にシグナルハンドラを張ってシグナル待ちをするのが一番素直かと個人的には思います。
package main import ( "context" "os/signal" "syscall" ) func main() { ctx, _ := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) <-ctx.Done() }
signal.NotifyContext
は、キャンセルのための stop
を返してくれるのですが、このプログラムはシグナルを受信すると即座に終了するため、技術的に不要です。
参考情報
Goのおすすめ書籍
過去の記事については、以下のページからご参照下さい。
サンプルコードは、以下の場所で公開しています。