본문으로 바로가기
728x90
반응형
728x170

BackEnd단에서 프로그램을 Go언어로 짜다 보면 Go 프로그램이 Unix signal을 처리해 주었으면 하는 때가 있죠.

 

예를 들어, SIGTERM signal을 받았을 때 적절하게 서버를 종료하는 경우나 커맨드라인 도구에서 SIGINT를 받았을 때 프로세스를 멈추는 경우가 그런 경우인데요. 오늘은 채널을 이용하여 signal을 다루는 방법을 살펴보겠습니다.

 

코드

package main

import "fmt"
import "os"
import "os/signal"
import "syscall"

func main() {
	sigs := make(chan os.Signal, 1)
	done := make(chan bool, 1)
    
    signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
    
    go func() {
		sig := <-sigs
		fmt.Println()
		fmt.Println(sig)
		done <- true
	}()
    
    fmt.Println("awaiting signal")
	<-done
	fmt.Println("exiting")
}

코드 설명

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

Go의 signal 알림은 os.Signal 값을 채널에 보내는 방식으로 작동합니다. 이런 알림을 받는 채널을 하나 만들어 줍니다.

(프로그램을 그만둬도 되는지 알려주는 채널도 만들 예정입니다.)

 

    signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

signal.Notify는 우리가 지정한 signal을 받을 수 있는 채널을 받고 등록해줍니다.

 

	go func() {
		sig := <-sigs
		fmt.Println()
		fmt.Println(sig)
		done <- true
	}()

이 Go routine은 signal을 받기 위한 차단 고루틴(blocking Go routine)입니다. Signal을 받으면 받은 signal을 출력하고 프 프로그램을 종료할 수 있음을 알려줍니다.

fmt.Println("awaiting signal")
	<-done
	fmt.Println("exiting")

프로그램은 여기에서 원하는 signal을 수신할 때까지 기다립니다. (위의 Go routine에서 signal를 받을 때까지 값을 보내는 것을 볼 수 있습니다.) 값을 받으면 종료됩니다.

 

실행결과

$ go run signals.go
awaiting signal
^C
interrupt
exiting

이 프로그램을 실행시키면 signal을 받을 때까지 block 될 것입니다. ctrl-C (^C로 표시됩니다.) 를 눌러서 SIGINT를 보낼 수 있습니다. SIGINT를 받은 프로그램은 interrupt를 출력하고 종료될 것입니다.

 

출처 : https://gobyexample.com/signals

       https://pkg.go.dev/os/signal

728x90
반응형
그리드형

댓글을 달아 주세요