"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."
👨💻 안녕하세요, 윌리 프로젝트의 윌리 입니다.
Go 에서 시그널 이벤트를 처리하는 방법은 어떻게 되는지 간략히 알아보았습니다.
질문 >
Go 에서 시그널 이벤트를 처리하는 방법은 어떻게 되나요?
답변 >
Go에서 시그널(signal) 이벤트를 처리하기 위해 os/signal 패키지와 os 패키지를 사용합니다. 이를 통해 프로세스가 운영 체제에서 전달하는 시그널을 수신하고 처리할 수 있습니다. 이는 프로세스 종료, 인터럽트, 재시작 등을 관리하는 데 유용합니다.
1. 주요 개념
- 시그널은 운영 체제가 프로세스에 특정 이벤트를 알리기 위해 사용하는 메커니즘입니다.
- Go의 os/signal 패키지는 시그널을 처리하는 API를 제공합니다.
- 일반적으로 처리되는 시그널:
- SIGINT (Ctrl+C): 프로세스 종료 요청.
- SIGTERM: 시스템이 프로세스를 종료하려고 할 때.
- SIGHUP: 터미널 연결이 끊어졌을 때.
- SIGKILL: 강제 종료(처리 불가).
2. 시그널 처리 기본 흐름
- 시그널 채널 생성:
- 시그널은 채널로 전달됩니다.
- os.Signal 타입의 채널을 생성해야 합니다.
- 시그널 알림 등록:
- signal.Notify를 사용하여 특정 시그널을 채널에 연결합니다.
- 시그널 수신 및 처리:
- 채널에서 수신한 시그널에 대해 처리 로직을 작성합니다.
- 프로그램 종료 처리:
- 종료 시 필요한 정리 작업을 수행합니다.
3. 코드 예제
3.1. 기본 시그널 처리
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
)
func main() {
// 시그널 채널 생성
signalChannel := make(chan os.Signal, 1)
// 처리할 시그널 등록
signal.Notify(signalChannel, syscall.SIGINT, syscall.SIGTERM)
// 시그널 수신 대기
fmt.Println("Waiting for signals... (press Ctrl+C to exit)")
sig := <-signalChannel
// 시그널 처리
fmt.Printf("Received signal: %s\\n", sig)
fmt.Println("Exiting gracefully...")
}
실행 결과
- 프로그램 실행 후 대기.
- Ctrl+C (SIGINT)를 누르면:
Waiting for signals... (press Ctrl+C to exit)
Received signal: interrupt
Exiting gracefully...
3.2. 고루틴을 사용한 비동기 처리
시그널 수신을 비동기로 처리하여 메인 작업과 병렬로 실행할 수 있습니다.
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"time"
)
func main() {
// 시그널 채널 생성
signalChannel := make(chan os.Signal, 1)
signal.Notify(signalChannel, syscall.SIGINT, syscall.SIGTERM)
// 시그널 처리 고루틴
go func() {
sig := <-signalChannel
fmt.Printf("Received signal: %s\\n", sig)
fmt.Println("Performing cleanup...")
time.Sleep(2 * time.Second)
fmt.Println("Cleanup complete. Exiting...")
os.Exit(0)
}()
// 메인 작업
fmt.Println("Application is running. Press Ctrl+C to stop.")
for {
fmt.Println("Working...")
time.Sleep(1 * time.Second)
}
}
3.3. 특정 시그널에 따른 동작
여러 시그널을 등록하고 각 시그널에 따라 다른 동작을 수행할 수 있습니다.
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
)
func main() {
// 시그널 채널 생성
signalChannel := make(chan os.Signal, 1)
signal.Notify(signalChannel, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)
// 시그널 수신 대기
for {
sig := <-signalChannel
switch sig {
case syscall.SIGINT:
fmt.Println("Received SIGINT (Ctrl+C). Shutting down...")
os.Exit(0)
case syscall.SIGTERM:
fmt.Println("Received SIGTERM. Terminating...")
os.Exit(0)
case syscall.SIGHUP:
fmt.Println("Received SIGHUP. Reloading configuration...")
// 설정 다시 로드 로직 추가 가능
}
}
}
3.4. 시그널 알림 중지
signal.Stop을 사용하여 특정 시그널 알림을 중지할 수 있습니다.
signal.Stop(signalChannel)
4. 유의사항
- SIGKILL과 SIGSTOP은 처리 불가:
- 이 시그널은 운영 체제가 강제로 처리하며, 애플리케이션에서 이를 가로챌 수 없습니다.
- 채널 버퍼 크기:
- 시그널 채널은 버퍼를 사용해야 하며, 버퍼가 없으면 채널이 블로킹됩니다.
- 정리 작업:
- 종료 시 필요한 작업(예: 파일 닫기, 데이터 저장 등)을 잊지 말고 처리하세요.
5. 결론
Go에서 시그널을 처리하는 것은 서버 애플리케이션과 같은 장기 실행 프로그램에서 필수적입니다. os/signal 패키지를 사용하면 특정 시그널에 반응하거나 프로세스 종료 시 정리 작업을 수행할 수 있습니다. 위 코드를 참조하여 애플리케이션 요구 사항에 맞는 시그널 처리 로직을 구현할 수 있습니다.
🎬 유튜브 채널 🎬
위로그@WiLog
📢 안녕하세요, 위로그@WiLog 시청자 여러분, 저는 윌리(Willee) 입니다. 📢 위로그@WiLog 는 자기계발을 목적으로 하는 채널 입니다. 📢 오늘도 즐겁게~ 자신을 위한 계발을 함께 해보아요~ d^_^b 📌
www.youtube.com
🎬 치지직 채널 🎬
위로그 채널 - CHZZK
지금, 스트리밍이 시작됩니다. 치지직-
chzzk.naver.com
'프로그래밍' 카테고리의 다른 글
👨💻 [Go] Go 에서 상위 패키지와 하위 패키지를 구분하는 방법이 어떻게 되나요? (0) | 2025.01.15 |
---|---|
👨💻 [Go] Go 에서 패키지 내부에 여러개의 go 파일로 나눠서 구현하는 방법은 어떻게 되나요? (0) | 2025.01.15 |
👨💻 [Go] Go 에서 모듈과 패키지의 이름을 짓는 규칙은 어떻게 되나요? (0) | 2025.01.15 |
👨💻 [C++] C++ 의 ev++ 에서 ev::sig 는 무엇이며, 어떻게 활용할 수 있나요? (0) | 2025.01.14 |
👨💻 [C++] C++ 에서 evbase 는 무엇이며, 어떻게 활용할 수 있나요? (0) | 2025.01.14 |