golang信号捕捉と処理

5316 ワード

notifyメソッドのプロトタイプ:
             func   Notify(c chan

   
    , 。

1.

1.1

package main

import (
    "fmt"
    "os"
    "os/signal"
    //"syscall"
)

func main() {
    c := make(chan os.Signal)
    signal.Notify(c)
    s :=     fmt.Println("get signal:", s)
}

1.2  Ctrl+C

package main

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

func main() {
    signalChan := make(chan os.Signal, 1)
    cleanupDone := make(chan bool)
    signal.Notify(signalChan, os.Interrupt)
    go func() {
        for _ = range signalChan { // Ctrl+C
            fmt.Println("
, ...
")
            cleanup()
            cleanupDone         }
    }()
    }

func cleanup() {
    fmt.Println(" ...
")
}

1.3 SIGUSR2 ,

package main

import (
    "fmt"
    "os"
    "os/signal"
    "syscall"
)

func main() {
    c := make(chan os.Signal)
    signal.Notify(c, syscall.SIGUSR2)
    // , for     //signal.Stop(c)

    for {
        s :=         fmt.Println("get signal:", s)
    }

}

1.4 chan

package main

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

func main() {
    go input()

    exit := make(chan os.Signal, 1)
    done := make(chan bool)

    signal.Notify(exit, os.Interrupt)

    go func() {
        for _ = range exit {
            fmt.Println("
")
            done         }
    }()

     }

func input() {
    var sum, input float64
    var numbers []float64

    sum = 0
    numbers = make([]float64, 0)

    fmt.Println("Number:")

    for {
        input = 0

        fmt.Scanln(&input)
        if input == 0 {
            break
        }

        numbers = append(numbers, input)
    }

    for _, v := range numbers {
        sum += v
    }

    fmt.Println("Result: ", sum)
    fmt.Println("Press ctrl+c to exit")
}

2.

package main

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

var stopFlag_ bool

type SignalHandler func(s os.Signal, arg interface{})

type SignalSet struct {
    m map[os.Signal]SignalHandler
}

func SignalSetNew() *SignalSet {
    ss := new(SignalSet)
    ss.m = make(map[os.Signal]SignalHandler)
    return ss
}

func (set *SignalSet) Register(s os.Signal, handler SignalHandler) {
    if _, found := set.m[s]; !found {
        set.m[s] = handler
    }
}

func (set *SignalSet) Handle(sig os.Signal, arg interface{}) (err error) {
    if _, found := set.m[sig]; found {
        set.m[sig](sig, arg)
        return nil
    } else {
        return fmt.Errorf("No handler available for signal %v", sig)
    }
    panic("won't reach here")
}

func main() {

    sigHandler := SignalSetNew()
    sigHandler.Register(syscall.SIGQUIT, sigHandlerFunc)  //
    sigHandler.Register(syscall.SIGUSR1, sigHandlerFunc)
    sigHandler.Register(syscall.SIGUSR2, sigHandlerFunc)
    sigChan := make(chan os.Signal, 10)  // os.Signal channel, signal.Notify
    signal.Notify(sigChan) 

    for true { // for+select , default
        select {
        case sig :=             err := sigHandler.Handle(sig, nil)
            if err != nil {
                fmt.Printf("[ERROR] unknown signal received: %v
", sig)
                os.Exit(1)
            }
        default:
            time.Sleep(time.Duration(3) * time.Second)
        }
    }
}

func sigHandlerFunc(s os.Signal, arg interface{}) {
    switch s {
    case syscall.SIGUSR1: // check
        fmt.Printf("stopping Status : %v
", stopFlag_)
    case syscall.SIGUSR2: // run
        formerFlag := stopFlag_
        stopFlag_ = false
        fmt.Printf("stopping Status changed from %v to %v
", formerFlag, stopFlag_)
    case syscall.SIGQUIT: // stop
        formerFlag := stopFlag_
        stopFlag_ = true
        fmt.Printf("stopping Status changed from %v to %v
", formerFlag, stopFlag_)
    }
}