[Go 04] 信號處理和退出程式

一般在執行go run main.go後就會馬上回到命令列,
這邊實作當接收到ctrl+c或是終止程式才會停止程式

本文說明:

  • go實作接收命令而中止程式.
  • 會用到channel管道來進行阻塞,並接收os/signal訊號

程式碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
func main() {
fmt.Println("start")
errs := make(chan error, 1)
listenForSignal(errs)
c := <-errs //阻塞程式
fmt.Println("terminating:", c)
}

func listenForignal(errChan chan error) {
go func() {
c := make(chan os.Signal,1)
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)//要終止的訊號

errChan <- fmt.Errorf("%s", <-c)
}()
}

說明:

使用”os/signal”包,用來接收訊號使用,notify方法用来監聽收到的信號(stop方法則取消)
* SIGINT 表示用户按下INTR字符(Ctrl+C)觸發
* SIGTERM 结束程序 kill pid的作用是向進程為pid的程序发送SIGTERM
* 其他像是SIGKILL kill -9 pid則是發送立即終止 等等就先不使用

測試接收SIGINT

然後執行go run main.go後,會看到服務就一直執行著,再按下ctrl+c

1
2
3
> go run main.go
start
^Cterminating: interrupt

測試接收SIGTERM

先將main.go編譯成執行檔 -o代表放在目前目錄下 取名為demo
“./“執行demo這檔案

1
2
3
go build -o ./demo  main.go
./demo
start

接下來開另一視窗 找出進程跟demo有關的pid 然後執行kill pid,確認已停止了

1
2
3
4
➜  ~ ps -A  | grep demo     
14693 ttys000 0:00.00 ./demo
➜ ~ kill 14693
➜ ~ ps -A | grep demo

回到程式執行視窗就會看到以下被中止的訊息了

1
2
3
 ./demo
start
terminating: terminated

後記疑問:

  1. 不太知道到底要怎麼要在vscode debug模式
    去模擬ctrl+c時會跑到的地方來看程式,google未有結果,無解
  2. 在linux環境有效,win環境搜尋無解
作者

Mini Lab Memo

發表於

2020-05-01

更新於

2023-03-11

許可協議

評論