콘솔에서 보낸 Ctrl+C( SIGINT
) 신호 를 캡처하고 부분 실행 합계를 인쇄하고 싶습니다 .
골랑에서 가능합니까?
참고 : 내가 먼저 질문을 게시 할 때 나는에 대해 혼란스러워했다 Ctrl+C되는 SIGTERM
대신 SIGINT
.
답변
os / signal 패키지를 사용하여 들어오는 신호를 처리 할 수 있습니다 . Ctrl+ C는 SIGINT 이므로이를 사용하여 트랩 할 수 있습니다 os.Interrupt
.
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
go func(){
for sig := range c {
// sig is a ^C, handle it
}
}()
프로그램을 종료하고 정보를 인쇄하는 방식은 전적으로 귀하에게 달려 있습니다.
답변
이것은 작동합니다 :
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"time" // or "runtime"
)
func cleanup() {
fmt.Println("cleanup")
}
func main() {
c := make(chan os.Signal)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() {
<-c
cleanup()
os.Exit(1)
}()
for {
fmt.Println("sleeping...")
time.Sleep(10 * time.Second) // or runtime.Gosched() or similar per @misterbee
}
}
답변
다른 답변에 약간 더하기 위해 실제로 SIGTERM (kill 명령으로 전송 된 기본 신호)을 잡으려면 syscall.SIGTERM
os.Interrupt 대신 사용할 수 있습니다 . syscall 인터페이스는 시스템에 따라 다르며 모든 곳에서 작동하지 않을 수 있습니다 (예 : Windows). 그러나 두 가지를 모두 잘 잡을 수 있습니다.
c := make(chan os.Signal, 2)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
....
답변
위의 허용 된 답변에 하나 또는 두 개의 작은 오타가 있었으므로 여기에 정리 된 버전이 있습니다. 이 예에서는 Ctrl+를 수신 할 때 CPU 프로파일 러를 중지합니다 C.
// capture ctrl+c and stop CPU profiler
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
go func() {
for sig := range c {
log.Printf("captured %v, stopping profiler and exiting..", sig)
pprof.StopCPUProfile()
os.Exit(1)
}
}()
답변
위의 모든 내용은 접속했을 때 작동하는 것처럼 보이지만 gobyexample의 신호 페이지 에는 신호를 캡처하는 데 대한 깨끗하고 완전한 예가 있습니다. 이 목록에 추가 할 가치가 있습니다.
답변
Death 는 채널과 대기 그룹을 사용하여 종료 신호를 기다리는 간단한 라이브러리입니다. 신호가 수신되면 정리하려는 모든 구조체에서 close 메소드를 호출합니다.
답변
당신은 syscall.SIGINT 및 syscall.SIGTERM 신호를 감지하는 다른 goroutine을 가지고 사용 채널로 중계 할 수 signal.Notify을 . 채널을 사용하여 해당 고 루틴에 후크를 보내고 함수 슬라이스에 저장할 수 있습니다. 채널에서 종료 신호가 감지되면 슬라이스에서 해당 기능을 실행할 수 있습니다. 자원을 정리하고 실행중인 goroutines가 완료 될 때까지 기다리거나 데이터를 유지하거나 부분 실행 합계를 인쇄하는 데 사용할 수 있습니다.
종료시 후크를 추가하고 실행하는 작고 간단한 유틸리티를 작성했습니다. 도움이 되길 바랍니다.
https://github.com/ankit-arora/go-utils/blob/master/go-shutdown-hook/shutdown-hook.go
이를 ‘지연’방식으로 수행 할 수 있습니다.
서버를 정상적으로 종료하는 예 :
srv := &http.Server{}
go_shutdown_hook.ADD(func() {
log.Println("shutting down server")
srv.Shutdown(nil)
log.Println("shutting down server-done")
})
l, err := net.Listen("tcp", ":3090")
log.Println(srv.Serve(l))
go_shutdown_hook.Wait()