overview
バックグラウンド等で動かすgoroutineを使ったforループプログラムで、シグナルを受け取った際に終了させる処理例
example1
ここではシグナルの代わりに適当なチャンネルを使う。
package main
import (
"fmt"
"time"
)
func main() {
c := make(chan string, 1)
sig := make(chan string, 1)
go func(){
for{
fmt.Println("Hello")
select{
case s := <-c:
fmt.Println(s)
sig<-"FINISH"
return
default:
}
time.Sleep(1 * time.Second) //
}
}()
time.Sleep(10 * time.Second)
c<-"done"
s:= <-sig
fmt.Println(s)
}
example2
実際にシグナルを使った例
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"time"
)
func Loop(c chan os.Signal, done chan int) {
go func() {
for {
fmt.Println("do something....")
select {
case s := <-c:
fmt.Println("Got signal:", s)
close(c)
done <- 0
return
default:
}
time.Sleep(1 * time.Second)
}
}()
}
func main() {
sig := make(chan os.Signal, 1)
signal.Notify(sig, syscall.SIGTERM, syscall.SIGINT)
done := make(chan int)
defer close(done)
Loop(sig, done)
<-done
fmt.Println("Exit")
os.Exit(0)
}
実行結果
-
main
ではdoneチャンネル受信待ちにする。 - シグナルを送るとチャンネルに送信される。
- 所定の処理が終わったあとにチャネルを受信する。シグナルが来ていなければ処理を継続。シグナルが来ている場合は
done
チャンネルに送信する、mainでdone
チャンネルを受信し処理を終了する。
$ go run signal.go
do something....
do something....
do something....
do something....
do something....
do something....
do something....
do something....
do something....
do something....
do something....
^Cdo something....
Got signal: interrupt
Exit