프로세스를 정상적으로 종료하려면 어떤 순서로 신호를 보내야 합니까?

StackOverflow https://stackoverflow.com/questions/690415

문제

안에 논평 ~에 이 답변 다른 사람의 질문, 댓글 작성자는 다음과 같이 말합니다.

절대적으로 필요한 경우 킬 -9를 사용하지 마십시오!Sigkill은 갇힐 수 없으므로 킬링 프로그램이 셧다운 루틴을 실행할 수 없습니다.임시 파일을 지우십시오.먼저 HUP (1), int (2)를 시도한 다음 종료 (3)

나는 원칙적으로 다음 사항에 동의합니다. SIGKILL, 그러나 나머지는 나에게 새로운 소식입니다.기본 신호가 전송된다는 점을 고려하면 kill ~이다 SIGTERM, 임의 프로세스의 정상적인 종료에 대해 가장 일반적으로 예상되는 신호일 것으로 예상됩니다.또한, 내가 본 SIGHUP "구성 파일을 다시 읽으십시오"라는 데몬에 대해 말하는 것과 같은 터미네이션이 아닌 이유에 사용됩니다. 그리고 그것은 나에게 보인다 SIGINT (일반적으로 Ctrl-C를 사용하여 얻을 수 있는 것과 동일한 인터럽트입니다. 그렇죠?) 예상만큼 널리 지원되지 않거나 다소 비정상적으로 종료됩니다.

을 고려하면 SIGKILL 최후의 수단이다 - 어떤 신호, 어떤 순서로, 가능한 한 정상적으로 종료하기 위해 임의의 프로세스에 보내야 합니까?

가능하다면 뒷받침하는 사실(개인적 선호나 의견을 넘어서)이나 참고 자료를 사용하여 답변을 입증해 주십시오.

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

편집하다: 지금까지 아무도 INT나 QUIT를 언급하지 않은 것 같고 HUP에 대한 언급도 제한적입니다.이를 순차적인 프로세스 종료에 포함시킬 이유가 있습니까?

도움이 되었습니까?

해결책

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

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

신호의 실제 의미가 무엇인지에 대한 자세한 내용은 sigaction(2)을 참조하십시오."기본 동작"과 "설명"을 혼동하지 마십시오. 둘은 같은 것이 아닙니다.

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

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

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

SIGKILL을 보내지 마세요. SIGKILL은 절대 스크립트로 전송되어서는 안 됩니다.애플리케이션이 SIGTERM을 처리하는 경우 정리하는 데 1초가 걸릴 수 있고, 한 시간 정도 걸릴 수 있어요.애플리케이션이 종료될 준비가 되기 전에 수행해야 하는 작업에 따라 다릅니다."라는 어떤 논리도가정하다" 애플리케이션의 정리 순서가 너무 오래 걸려 X초 후에 바로가기 또는 SIGKILL이 필요합니다. 그냥 확실히 틀렸어.

신청서를 제출하는 유일한 이유 필요 종료할 SIGKILL은 정리 과정 중에 버그가 발생한 경우입니다.이 경우 터미널을 열고 수동으로 SIGKILL할 수 있습니다.그 외에도 SIGKILL을 수행하는 유일한 이유는 다음과 같습니다. 원하다 스스로 청소되는 것을 방지하기 위해.

세계의 절반이 5초 후에 맹목적으로 SIGKILL을 보내더라도 이는 여전히 끔찍한 잘못된 행동입니다.

다른 팁

짧은 답변:보내다 SIGTERM, 30초 후, SIGKILL.즉, 보내다 SIGTERM, 조금 기다려주세요(프로그램마다 다를 수 있으며 시스템을 더 잘 알 수도 있지만 5~30초이면 충분합니다.머신을 종료할 때 최대 1분 30초까지 자동으로 대기하는 것을 볼 수 있습니다.결국 왜 서두르나요?) 그런 다음 보내세요. SIGKILL.

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

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

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

이 설명에서 어떤 답을 선택하든 이 점을 명심하세요!

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

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

거의 멍청한 긴 답변:

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

사용하라고 제안하는 순서대로 주문했습니다. (그런데, 다음을 사용하는 것이 좋습니다. 합리적인 대답, 여기서는 아님), 정말로 모두 시도해야 한다면(표가 발생할 수 있는 파괴 측면에서 순서가 지정되어 있다고 말하는 것이 재미있을 것입니다. 그러나 그것은 그렇지 않습니다.) 완전히 진실).

별표(*)가 있는 신호는 다음과 같습니다. 아니다 추천합니다.이것에 대한 중요한 점은 그것이 무엇을 하도록 프로그래밍되어 있는지 결코 알 수 없다는 것입니다.특별히 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.

SIGUSR2 전에 시도해야 SIGUSR1 왜냐하면 프로그램이 신호를 처리하지 않는 것이 더 나을 것이기 때문입니다.그리고 그것이 처리될 가능성이 훨씬 더 높습니다 SIGUSR1 그 중 하나만 처리하는 경우.

그런데, 킬:보낸 게 잘못은 아니지 SIGKILL 다른 답변에서 언급했듯이 프로세스에.음, 당신이 메시지를 보내면 무슨 일이 일어날지 생각해 보세요. shutdown 명령?노력할 것이다 SIGTERM 그리고 SIGKILL 오직.왜 그런 것 같나요?그리고 왜 다른 신호가 필요한가요? shutdown 명령은 이 두 가지만 사용합니까?


이제 다시 긴 대답, 이것은 좋은 oneliner입니다:

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

신호 사이에 30초 동안 대기합니다.왜 또 필요하겠습니까? 짧막 한 농담? ;)

또한 권장되는 사항은 다음과 같습니다.신호만으로 시도해 보세요 15 2 9 ~로부터 합리적인 대답.

안전:두 번째 제거 echo 갈 준비가 되면.나는 그것을 내 것이라고 부른다. dry-run ~을 위한 온라인 사용자.항상 테스트에 사용하십시오.


스크립트 종료

사실 저는 이 질문에 너무 흥미를 느껴서 이를 수행하기 위한 작은 스크립트를 만들기로 결정했습니다.여기에서 자유롭게 다운로드(복제)하세요.

GitHub 링크 Killgraceously 저장소

일반적으로 보내드립니다 SIGTERM, 킬의 기본값. 이유의 기본입니다. 프로그램이 합리적인 시간 내에 종료되지 않은 경우에만 의지해야합니다. SIGKILL. 그러나 그와 함께하십시오 SIGKILL 이 프로그램은 UND 데이터를 손상시킬 가능성이 없습니다.

에 관해서 SIGHUP, HUP "끊기"를 나타내며 역사적으로 모뎀이 연결이 끊어 졌음을 의미했습니다. 본질적으로 동일합니다 SIGTERM. 데몬이 때때로 사용하는 이유 SIGHUP 구성을 다시 시작하거나 다시로드하는 것은 데몬이 필요하지 않으므로 제어 터미널에서 데몬이 분리되어서는 절대받지 못할 것입니다. SIGHUP, 따라서 신호는 일반적인 용도로 "해제"로 간주되었습니다. 모든 데몬이 다시로드에 이것을 사용하는 것은 아닙니다! Sighup의 기본 행동은 종료되는 것이며 많은 데몬이 그렇게 행동합니다! 그래서 당신은 맹목적으로 보낼 수 없습니다 SIGHUPS는 데몬에게 그리고 그들이 살아남을 것으로 기대합니다.

편집하다: SIGINT 일반적으로 묶인 프로세스를 종료하는 것은 부적절 할 것입니다. ^C 또는 터미널 설정이 프로그램을 방해하는 것이 무엇이든. 많은 프로그램들이 그들 자신의 목적을 위해 이것을 포착하므로 작동하지 않을 정도로 일반적입니다. SIGQUIT 일반적으로 핵심 덤프를 생성하는 기본값이 있으며, 코어 파일을 주위에 놓기를 원하지 않는 한 좋은 후보도 아닙니다.

요약 : 보내는 경우 SIGTERM 그리고 프로그램은 당신의 시간대 안에 죽지 않고 그것을 보내십시오 SIGKILL.

SIGTERM 실제로는 애플리케이션에 메시지를 보내는 것을 의미합니다."그렇게 친절하게 대해주고 자살할래?".정리 및 종료 코드를 실행하기 위해 애플리케이션에서 이를 트랩하고 처리할 수 있습니다.

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

보내는 것이 일반적입니다. SIGTERM 먼저 좀 자고 나서 보내 SIGKILL.

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

모든 토론이 진행되면서 코드가 제공되지 않았습니다. 내 테이크는 다음과 같습니다.

#!/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

Hup은 저에게 쓰레기처럼 들립니다. 구성을 다시 읽기 위해 데몬을 얻기 위해 보냅니다.

SIGTERM은 가로 채울 수 있습니다. 데몬은 해당 신호를받을 때 실행할 정리 코드가있을 수 있습니다. Sigkill을 위해 그렇게 할 수 없습니다. 따라서 Sigkill을 사용하면 데몬의 저자에게 옵션을 제공하지 않습니다.

그것에 대해 더 위키 백과

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top