정상 종료 프로세스에 신호를 어떤 순서로 보내야합니까?


88

다른 질문 에 대한 이 답변 에 대한 의견 에서 댓글 작성자는 다음과 같이 말합니다.

꼭 필요한 경우가 아니면 kill -9를 사용하지 마십시오! SIGKILL은 트랩 될 수 없으므로 종료 된 프로그램은 임시 파일을 지우는 등의 종료 루틴을 실행할 수 없습니다. 먼저 HUP (1), INT (2), QUIT (3)을 차례로 시도합니다.

에 대해 원칙적으로 동의 SIGKILL하지만 나머지는 나에게 뉴스입니다. 에서 보낸 기본 신호 killSIGTERM인 경우 임의 프로세스의 정상 종료를 위해 가장 일반적으로 예상되는 신호라고 예상합니다. 또한 SIGHUP데몬에게 "설정 파일을 다시 읽습니다"라고 말하는 것과 같이 종료되지 않는 이유로 사용되는 것을 보았습니다 . 그리고 SIGINT(일반적으로 Ctrl-C로 얻는 것과 동일한 인터럽트)가 필요한만큼 널리 지원되지 않거나 다소 비정상적으로 종료되는 것 같습니다.

SIGKILL이것이 최후의 수단 이라는 점을 감안할 때 , 가능한 한 정상적으로 종료하기 위해 임의의 프로세스에 어떤 신호를 어떤 순서로 보내야합니까?

가능한 경우 뒷받침하는 사실 (개인의 선호도 또는 의견을 넘어서) 또는 참조로 답변을 입증하십시오.

참고 : 특히 bash / Cygwin을 고려하는 모범 사례에 관심이 있습니다.

편집 : 지금까지 아무도 INT 또는 QUIT를 언급하지 않았으며 HUP에 대한 언급이 제한되어 있습니다. 질서있는 프로세스 킬링에 이들을 포함시킬 이유가 있습니까?


4
정말로 프로세스를 죽이기 위해 SIGKILL에 의지해야한다면, 나는 그것을 프로그램의 버그라고 생각할 것입니다.
sigjuice

답변:


114

SIGTERM은 애플리케이션을 종료하도록 지시합니다. 다른 신호는 종료와 관련이 없지만 때때로 동일한 결과를 가질 수있는 다른 것들을 애플리케이션에 알려줍니다. 그것들을 사용하지 마십시오. 응용 프로그램을 종료하려면 알려주십시오. 오해의 소지가있는 신호를주지 마십시오.

어떤 사람들은 프로세스를 종료하는 현명한 표준 방법이 HUP, INT, TERM 및 마지막으로 KILL과 같은 수많은 신호를 보내는 것이라고 생각합니다. 이건 말도 안돼. 종료에 대한 올바른 신호는 SIGTERM이며 SIGTERM이 원하는대로 프로세스를 즉시 종료하지 않는 경우 응용 프로그램이 신호를 처리하도록 선택했기 때문입니다. 즉, 즉시 종료하지 않아야하는 아주 좋은 이유가 있습니다. 정리 작업이 필요합니다. 다른 신호와 함께 해당 정리 작업을 중단하면 아직 디스크에 저장하지 않은 메모리의 데이터, 중단 된 클라이언트 응용 프로그램 또는 효과적인 데이터 손상 인 "중간"중단 여부를 알 수 없습니다.

신호의 실제 의미에 대한 자세한 내용은 sigaction (2)을 참조하십시오. "기본 작업"과 "설명"을 혼동하지 마십시오. 동일하지 않습니다.

SIGINT는 프로세스의 대화 형 "키보드 인터럽트"를 알리는 데 사용됩니다. 일부 프로그램은 터미널 사용자를 위해 특수한 방식으로 상황을 처리 할 수 ​​있습니다.

SIGHUP는 터미널이 사라졌고 더 이상 프로세스를 보지 않는다는 신호를 보내는 데 사용됩니다. 그게 다입니다. 일부 프로세스는 일반적으로 터미널 없이는 작동이 의미가 없기 때문에 응답으로 종료하도록 선택하고 일부 프로세스는 구성 파일 재확인과 같은 다른 작업을 수행합니다.

SIGKILL은 커널에서 프로세스를 강제로 제거하는 데 사용됩니다. 실제로 프로세스에 대한 신호가 아니라 커널에 의해 직접 해석된다는 점에서 특별합니다.

SIGKILL을 보내지 마십시오. SIGKILL은 확실히 스크립트로 보내서는 안됩니다. 애플리케이션이 SIGTERM을 처리하는 경우 정리하는 데 1 초, 1 분, 1 시간이 소요될 수 있습니다 . 응용 프로그램이 종료 할 준비가되기 전에 수행해야하는 작업에 따라 다릅니다. 응용 프로그램의 정리 시퀀스가 ​​충분히 오래 걸리고 X 초 후에 바로 가기 또는 SIGKILLed가 필요 하다고 가정 하는 모든 논리는 잘못된 것 입니다.

응용 프로그램 을 종료하기 위해 SIGKILL 이 필요한 유일한 이유 는 정리 시퀀스 중에 버그가 발생한 경우입니다. 이 경우 터미널을 열고 수동으로 SIGKILL 할 수 있습니다. 그 외에도 무언가를 SIGKILL하는 유일한 다른 이유는 그것이 스스로 청소하는 것을 막고 싶기 때문 입니다.

전 세계의 절반이 5 초 후에 맹목적으로 SIGKILL을 보냈지 만 여전히 끔찍하게 잘못된 일입니다.


13
SIGKILL의 오용이 많다는 것이 맞습니다. 그러나 스크립트에서도 사용할 시간과 장소가 있습니다. 많은 앱이 SIGTERM을 트랩하고 1 초 이내에 또는 단 몇 초 내에 정상적으로 종료되며, 그중 하나는 여전히 30 초 후에 실행됩니다.
dwc

4
@dwc : 한 시간 동안 한 번 실행 해보십시오. 그것이 죽지 않는다면 그것은 "결혼"되고 그것을 고치거나 또는 게으르고 미래에 얼마 후에 그것을 SIGKILL합니다. 당신이 아마도 무언가를 손상시키고 있다는 점에 유의 하고 이것은 "기본적으로"해야 할 일이 아님을 기억하십시오.
lhunath

2
@lhunath : 괜찮 으시길 바랍니다. 질문에서보다 직접적이고 명확하게 답을하기 위해 단락을 재정렬했습니다. 반 SIGKILL 폭언은 좋은 물건이지만 부차적 인 요점입니다. 우수하고 교육적인 답변에 다시 한 번 감사드립니다.
시스템 PAUSE

8
SIGKILL을 보내지 마십시오. 이제까지. 그냥 틀렸어요. 정말? 무한 루프 덕분에 시스템이 이미 레코딩 중이더라도. 행운을 빕니다. -1
konsolebox

//, 찬성 투표 는 말도
Nathan Basanese

17

짧은 답변 : 전송 SIGTERM, 30 초 후, SIGKILL. 즉, 보내기 SIGTERM, 잠시 기다립니다 (프로그램마다 다를 수 있으며 시스템을 더 잘 알 수 있지만 5 ~ 30 초면 충분합니다. 시스템을 종료 할 때 자동으로 1 분 30 초까지 대기하는 것을 볼 수 있습니다. 왜 서둘러, 결국?), 다음 보낼 SIGKILL.

합리적인 답변 : SIGTERM, SIGINT, SIGKILL 이 충분 이상입니다. 이 프로세스는 것입니다 매우 아마도 이전에 종료 SIGKILL.

긴 대답 : SIGTERM, SIGINT, SIGQUIT, SIGABRT,SIGKILL

이것은 불필요하지만 적어도 귀하의 메시지와 관련된 프로세스를 오도하는 것은 아닙니다. 이러한 모든 신호 프로세스가 수행중인 작업을 중지하고 종료하기를 원한다는 것을 의미합니다.

이 설명에서 어떤 답을 선택하든 그 점을 명심하십시오!

다른 것을 의미하는 신호를 보내면 프로세스가 매우 다른 방식으로 처리 할 수 ​​있습니다. 반면에 프로세스가 신호를 처리하지 않으면 결국 무엇을 보내든 상관없이 프로세스가 종료됩니다 (물론 기본 작업이 종료되는 경우).

그래서 당신은 자신을 프로그래머로 생각해야합니다. SIGHUP무언가와 연결된 프로그램을 종료하기 위해 함수 핸들러를 코딩 하시겠습니까 , 아니면 다시 연결을 시도하기 위해 반복 하시겠습니까? 이것이 여기서 주요 질문입니다! 그렇기 때문에 의도 한 바를 의미하는 신호 만 보내는 것이 중요합니다.

거의 어리석은 긴 대답 :

아래 표에는 관련 신호와 프로그램이 처리하지 않는 경우의 기본 동작이 포함되어 있습니다.

나는 내가 제안한 순서대로 주문했다 (BTW, 나는 여기가 아닌 합리적인 대답 을 사용하는 것이 좋습니다 ), 정말로 모든 것을 시도해야한다면 (테이블이 다음과 같이 정렬되어 있다고 말하는 것이 재미있을 것입니다. 그들이 야기 할 수있는 파괴, 그러나 그것은 완전히 사실 이 아닙니다 ).

별표 (*)가있는 신호는 권장 되지 않습니다. 이것들에 대한 중요한 것은 그것이 무엇을하도록 프로그램되어 있는지 결코 알 수 없다는 것입니다. 특별히 SIGUSR! 그것은 종말을 시작할 수 있습니다 (프로그래머가 원하는 것은 무엇이든 할 수있는 무료 신호입니다!). 그러나 처리되지 않거나 또는 드물게 종료 처리되면 프로그램이 종료됩니다.

표에서 코어 덤프를 종료하고 생성하는 기본 옵션이있는 신호는 SIGKILL.

Signal     Value     Action   Comment
----------------------------------------------------------------------
SIGTERM      15       Term    Termination signal
SIGINT        2       Term    Famous CONTROL+C interrupt from keyboard
SIGHUP        1       Term    Disconnected terminal or parent died
SIGPIPE      13       Term    Broken pipe
SIGALRM(*)   14       Term    Timer signal from alarm
SIGUSR2(*)   12       Term    User-defined signal 2
SIGUSR1(*)   10       Term    User-defined signal 1
SIGQUIT       3       Core    CONTRL+\ or quit from keyboard
SIGABRT       6       Core    Abort signal from abort(3)
SIGSEGV      11       Core    Invalid memory reference
SIGILL        4       Core    Illegal Instruction
SIGFPE        8       Core    Floating point exception
SIGKILL       9       Term    Kill signal

그럼 난 이것에 대한 제안 거의 바보 긴 대답 : SIGTERM, SIGINT, SIGHUP, SIGPIPE, SIGQUIT, SIGABRT,SIGKILL

그리고 마지막으로

확실히 어리석은 긴 긴 대답 :

집에서 이것을 시도하지 마십시오.

SIGTERM, SIGINT, SIGHUP, SIGPIPE, SIGALRM, SIGUSR2, SIGUSR1, SIGQUIT, SIGABRT, SIGSEGV, SIGILL, SIGFPE아무것도, 일을하지 않는 경우 SIGKILL.

SIGUSR2SIGUSR1프로그램이 신호를 처리하지 않으면 더 낫기 때문에 전에 시도해야합니다 . 그리고 SIGUSR1그것들 중 하나만 처리 하면 처리 할 가능성이 훨씬 더 높습니다 .

BTW, the KILL : SIGKILL다른 답변이 언급했듯이 프로세스 에 보내는 것은 잘못이 아닙니다 . 음, shutdown명령 을 보내면 어떻게 될지 생각해 ? 그것은 시도 할 것이다 SIGTERMSIGKILL단지. 왜 그렇다고 생각하십니까? shutdown명령이이 두 가지만 사용 한다면 왜 다른 신호가 필요 합니까?


이제 긴 대답으로 돌아가서 이것은 멋진 oneliner입니다.

for SIG in 15 2 3 6 9 ; do echo $SIG ; echo kill -$SIG $PID || break ; sleep 30 ; done

신호 사이에 30 초 동안 휴면합니다. 왜 oneliner 가 필요 합니까? ;)

또한, 추천 : 신호 만에 그것을 시도 15 2 9로부터 합리적인 대답 .

안전 : echo갈 준비가되면 두 번째를 제거하십시오 . 나는 그것을 내 전화 dry-run에 대한 onliners . 항상 테스트에 사용하십시오.


killgracefully 스크립트

사실 저는이 질문에 흥미를 느꼈기 때문에 작은 스크립트를 작성하기로 결정했습니다. 여기에서 다운로드 (복제)하십시오.

Killgracefully 저장소에 대한 GitHub 링크


8

일반적으로 SIGTERM기본값 인 kill을 전송 합니다. 이유에 대한 기본값입니다. 프로그램이 적절한 시간 내에 종료되지 않는 경우에만 SIGKILL. 그러나 SIGKILL프로그램 을 사용 하면 정리할 가능성이 없으며 데이터가 손상 될 수 있습니다.

에 관해서는 SIGHUP, HUP"전화를 끊고"의 약자 역사적 모뎀 연결이 끊어 것을 의미했다. 본질적으로 SIGTERM. 데몬이 SIGHUP구성을 다시 시작하거나 다시로드 하는 데 사용 하는 이유는 데몬 이 제어 터미널에서 분리되는 이유는 데몬 이 이러한 터미널을 필요로하지 않고 따라서 절대 수신하지 않기 때문입니다. 따라서 SIGHUP신호는 일반적으로 "해제 된"것으로 간주됩니다. 모든 데몬이 이것을 다시로드하는 것은 아닙니다! SIGHUP의 기본 동작은 종료이며 많은 데몬이 그런 방식으로 동작합니다! 그래서 당신은 맹목적으로 SIGHUPs를 데몬에 보내고 그들이 살아남기를 기대할 수 없습니다 .

편집 : SIGINT 일반적으로 ^C프로그램을 중단하는 터미널 설정에 연결되어 있기 때문에 프로세스를 종료하는 것은 부적절 할 수 있습니다. 많은 프로그램이 자체 목적으로 이것을 캡처하므로 작동하지 않는 것이 일반적입니다. SIGQUIT일반적으로 코어 덤프를 생성하는 기본값이 있으며 코어 파일을 배치하지 않는 한 좋은 후보가 아닙니다.

요약 : SIGTERM프로그램을 보낸 후 해당 기간 내에 프로그램이 종료되지 않으면 보내십시오 SIGKILL.


4
SIGKILL을 사용한 후속 조치는 데이터 손실 / 데이터 손상을 방지하는 것보다 즉시 종료하는 것이 우선 순위가 높은 상황에서만 수행해야합니다.
thomasrutter 2013-02-28

@dwc 귀하의 답변에서 다음 사항을 이해하지 못했습니다. "데몬이 때때로 SIGHUP를 사용하여 구성을 다시 시작하거나 다시로드하는 이유는 데몬이 제어 터미널에서 분리되어 SIGTERM을 수신하지 않기 때문입니다. 따라서 신호는 일반적으로"해제 "된 것으로 간주되었습니다."
Jack

3
@Jack Let me try : SIGHUP는 프로세스에 터미널 연결이 끊어 졌음을 알리는 "전화 끊기"신호입니다. 데몬은 백그라운드에서 실행되기 때문에 터미널이 필요하지 않습니다. 즉, "전화 끊기"신호는 데몬과 관련이 없습니다. 그들은 처음에 터미널이 연결되어 있지 않기 때문에 터미널 연결 해제로 인해 결코 수신하지 않습니다. 신호가 어쨌든 정의 되었기 때문에 원래 목적으로는 필요하지 않지만 많은 데몬은 대신 구성 파일을 다시 읽는 것과 같은 다른 목적으로 신호를 사용합니다.
시스템 PAUSE

감사합니다 시스템 PAUSE. 이것은 도움이됩니다.
Jack

6

SIGTERM실제로 응용 프로그램에 메시지를 보내는 것을 의미합니다. " 당신은 정말 친절하고 자살을 하시겠습니까 ". 정리 및 종료 코드를 실행하기 위해 애플리케이션에서 트랩 및 처리 할 수 ​​있습니다.

SIGKILL응용 프로그램에 의해 트랩 될 수 없습니다. 응용 프로그램은 정리할 기회없이 OS에 의해 종료됩니다.

SIGTERM먼저 전송 하고 잠시 자고을 전송하는 것이 일반적 SIGKILL입니다.


나는 가정 폴링합니다 (SIGKILL 전) 수면보다 좀 더 효율적인 것
오핫 슈나이더

@OhadSchneider는 그럴 것이지만 간단한 bash 명령 이상의 것이 필요합니다.
vartec

예, 다음과 같은 것을 사용하여 프로세스가 아직 살아있는 동안 반복해야 할 것 같습니다 : stackoverflow.com/a/15774758/67824 .
Ohad Schneider

5
  • SIGTERM은 창에서 " 'X'를 클릭"하는 것과 같습니다.
  • SIGTERM은 Linux가 종료 될 때 가장 먼저 사용하는 것입니다.

그것이 내가 알고 싶었던 것입니다. +1. 감사.

6
"SIGTERM은"창에서 'X'를 클릭 "하는 것과 동일합니다. 아니요, 하나의 응용 프로그램이 대화 상자는 물론 여러 개의 창 (예 : 문서 및 도구)을 쉽게 열 수 있고 그렇지 않을 수도 있기 때문입니다. 종료 명령과 마찬가지로 마지막 창 닫기 명령에도 응답합니다 (명백한 예는 생각할 수 없지만 명확하지 않지만 그렇게 할 수없는 이유는 없습니다). SIGTERM은 애플리케이션 종료를 정상적으로 요청하는 것과 동일하거나 동일해야 하지만 해당 특정 애플리케이션에서 수행 될 수 있습니다 .
사용자

3

여기에서 진행되는 모든 논의와 함께 코드가 제공되지 않았습니다. 내 의견은 다음과 같습니다.

#!/bin/bash

$pid = 1234

echo "Killing process $pid..."
kill $pid

waitAttempts=30 
for i in $(seq 1 $waitAttempts)
do
    echo "Checking if process is alive (attempt #$i / $waitAttempts)..."
    sleep 1

    if ps -p $pid > /dev/null
    then
        echo "Process $pid is still running"
    else
        echo "Process $pid has shut down successfully"
        break
    fi
done

if ps -p $pid > /dev/null
then
    echo "Could not shut down process $pid gracefully - killing it forcibly..."
    kill -SIGKILL $pid
fi

0

HUP는 나에게 쓰레기처럼 들린다. 나는 그것의 구성을 다시 읽을 데몬을 얻기 위해 그것을 보낼 것입니다.

SIGTERM은 가로 챌 수 있습니다. 데몬은 신호를 수신 할 때 실행할 정리 코드를 가질 수 있습니다. SIGKILL에는 그렇게 할 수 없습니다. 따라서 SIGKILL을 사용하면 데몬 작성자에게 옵션을 제공하지 않습니다.

Wikipedia 에서 더 알아보기

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.