いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-265 (シグナル通知設定をリセットする)(signal.Reset)

概要

以下、自分用のメモです。よく忘れるのでここにメモメモ。。。

シグナルのハンドリングは、signal.Notifysignal.NotifyContext で行いますが

たまに、リセットしたいときもあります。

その場合は、signal.Reset を利用します。

サンプル

// signal.Reset() のサンプルです。
//
// # REFERENCES
//   - https://www.developer.com/languages/os-signals-go/
//   - https://pkg.go.dev/os/signal@go1.19.3#Reset
package main

import (
    "context"
    "fmt"
    "os"
    "os/signal"
    "time"
)

func main() {
    ctx, cxl := context.WithCancel(context.Background())
    defer cxl()

    // 0. 待機用
    waitCtx, waitCxl := context.WithTimeout(ctx, 5*time.Second)
    defer waitCxl()

    // 1. SIGINT を Notify しておく
    sigCh := make(chan os.Signal, 1)
    signal.Notify(sigCh, os.Interrupt)

    // 2. SIGINT のハンドリングと signal.Reset() の呼び出し
    fmt.Println("5秒間 SIGINT をハンドリング")
    go func() {
    LOOP:
        for {
            select {
            case <-waitCtx.Done():
                fmt.Fprintln(os.Stderr, "signal.Reset() CALLED")
                signal.Reset(os.Interrupt)
                break LOOP
            case <-sigCh:
                fmt.Fprintln(os.Stderr, "CTRL-C PRESSED")
            }
        }
    }()

    // 3. signal.Reset() 後の挙動確認 (CTRL-C 押下で元の動き(アプリ終了)に戻っていることの確認)
    <-waitCtx.Done()
    <-time.After(5 * time.Second)
}

実行すると以下のようになります。

$ go run .
5秒間 SIGINT をハンドリング
^CCTRL-C PRESSED
^CCTRL-C PRESSED
^CCTRL-C PRESSED
signal.Reset() CALLED
^Csignal: interrupt

signal.Reset を設定した後は、CTRL-C (SIGINT) を送るとデフォルトの動作(アプリ終了)に戻ります。

参考情報

try-golang/examples/signal/reset at master · devlights/try-golang · GitHub

Go言語による並行処理

Go言語による並行処理

Amazon


過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。