답변:
kill -9
( SIGKILL )은 프로세스를 종료 할 권한이있는 경우 항상 작동합니다. 기본적으로 프로세스는 setuid 또는 setgid가 아니어야 시작하거나 루트 여야합니다. 한 가지 예외가 있습니다. root조차도 치명적인 신호를 PID 1 ( init
프로세스)로 보낼 수 없습니다 .
그러나 즉시kill -9
작동하지는 않습니다 . SIGKILL을 포함한 모든 신호는 비동기 적으로 전달됩니다. 커널이 신호를 전달하는 데 시간이 걸릴 수 있습니다. 일반적으로 신호를 전달하는 데 최대 몇 마이크로 초가 걸리며, 대상이 시간 조각을 얻는 데 걸리는 시간입니다. 그러나 대상이 신호 를 차단 한 경우 대상이 차단을 해제 할 때까지 신호가 대기됩니다.
일반적으로 프로세스는 SIGKILL을 차단할 수 없습니다. 그러나 커널 코드는 시스템 호출 을 호출 할 때 커널 코드를 실행할 수 있고 프로세스는 커널 코드를 실행할 수 있습니다 . 커널 호출은 시스템 호출을 방해 할 때 모든 신호를 차단하여 커널 어딘가에 데이터 구조가 잘못 형성되거나 더 일반적으로 일부 커널 불변이 위반 될 수 있습니다. 따라서 (버그 또는 잘못된 설계로 인해) 시스템 호출이 무기한으로 차단되면 프로세스를 종료시킬 수있는 방법이 사실상 없을 수 있습니다. 그러나 시스템 호출이 완료되면 프로세스 가 종료됩니다 .
시스템 호출에서 차단 된 프로세스는 무정전 절전 상태 입니다. ps
또는 top
명령 (대부분의 유닉스에) 상태로 표시됩니다 D
(원래 "에 대한 개발 ISK"나는 생각한다).
중단없는 긴 절전 모드의 전형적인 경우 는 서버가 응답하지 않을 때 NFS를 통해 파일에 액세스하는 프로세스입니다 . 현대적인 구현에서는 중단없는 절전 모드를 적용하지 않는 경향이 있습니다 (예 : Linux의 경우 intr
mount 옵션을 사용하면 신호가 NFS 파일 액세스를 방해 할 수 있음).
때때로 또는 출력에 표시된 항목 Z
(또는 H
Linux에서는 구별이 무엇인지 모르겠습니다)이 표시 될 수 있습니다 . 이들은 기술적으로 프로세스가 아니며 좀비 프로세스이며 프로세스 테이블의 항목에 불과하므로 부모 프로세스가 자식의 죽음을 알 수 있습니다. 부모 프로세스 가주의를 기울 이거나 죽으면 사라집니다 .ps
top
man 5 nfs
: " intr
/ nointr
mount 옵션은 커널 2.6.25 이후에는 더 이상 사용되지 않습니다. SIGKILL 만이 커널에서 보류중인 NFS 작업을 중단 할 수 있으며, 지정된 경우이 마운트 옵션은 무시되어 이전 커널과의 하위 호환성을 제공합니다."
sshfs
프로세스를 강제 종료 할 수 있습니다 (다른 FUSE 파일 시스템과 마찬가지로 강제로 마운트 해제 할 수 있음).
때때로 프로세스가 존재하며 다음으로 인해 종료 될 수 없습니다.
top
그것은 Z 신호입니다top
그것은 D.에 의해 신호입니다좀비 프로세스 가있는 것 같습니다 . 이것은 해롭지 않습니다. 좀비 프로세스가 소비하는 유일한 리소스는 프로세스 테이블의 항목입니다. 부모 프로세스가 죽거나 아이의 죽음에 반응하면 사라집니다.
top
또는 다음 명령 을 사용하여 프로세스가 좀비인지 확인할 수 있습니다 .
ps aux | awk '$8=="Z" {print $2}'
ps
. 모든 Unices에서 모든 구현 을 통해 필수 필드가 항상 8 일 것이라고 누가 확신 할 수 ps
있습니까?
단서가 있는지 /var/log/kern.log
및 /var/log/dmesg
/ 또는 동등한 것을 확인하십시오 . 내 경험상 이것은 NFS 마운트의 네트워크 연결이 갑자기 끊어 지거나 장치 드라이버가 충돌했을 때만 발생했습니다. 하드 드라이브가 충돌하면 발생할 수 있다고 생각합니다.
lsof
프로세스가 어떤 장치 파일을 열 었는지 확인할 수 있습니다 .
kill -9
보통 60 분을 기다린 후에도 작동하지 않았습니다. 유일한 해결책은 재부팅이었습니다.
@ Maciej 와 @ Gilles 의 답변으로 문제가 해결되지 않고 프로세스를 인식하지 못하면 (그리고 배포판에 무엇이 있는지 묻는 것이 답변을 얻지 못합니다). 루트킷 및 소유 한 다른 징후를 확인하십시오 . 루트킷은 프로세스를 종료시키지 못하게 할 수 있습니다. 실제로 많은 사람들이 당신이 그들을 보지 못하게 할 수 있습니다. 그러나 1 개의 작은 프로그램을 수정하는 것을 잊어 버린 경우 발견 될 수 있습니다 (예 : 수정 top
되었지만 수정 되지 않음 htop
). 아마도 이것은 사실이 아니지만 미안보다 안전합니다.
킬은 실제로 신호를 보내는 것을 의미합니다. 보낼 수있는 여러 신호가 있습니다. kill -9는 특별한 신호입니다.
신호를 보낼 때 응용 프로그램이 신호를 처리합니다. 그렇지 않으면 커널이 처리합니다. 애플리케이션에 신호를 포착 할 수 있습니다.
그러나 나는 살인 9가 특별하다고 말했다. 응용 프로그램이 얻지 못한다는 점에서 특별합니다. 커널로 직접 이동하여 가능한 첫 번째 기회에서 응용 프로그램을 실제로 종료합니다. 다른 말로하면 죽었다
kill -15는 SIGNAL TERMINATE를 나타내는 SIGTERM 신호를 전송합니다. 즉, 응용 프로그램이 종료되도록 지시합니다. 이것은 응용 프로그램에 종료 시간을 알려주는 친숙한 방법입니다. 그러나 응용 프로그램이 응답하지 않으면 kill -9가 종료합니다.
kill -9가 작동하지 않으면 아마도 커널에 문제가 있음을 의미합니다. 재부팅이 순서대로 이루어집니다. 나는 그 일이 일어났다는 것을 기억할 수 없다.
먼저 좀비 프로세스가 있는지 확인하십시오 (매우 가능합니다).
ps -Al
다음과 같은 것을 보게 될 것입니다 :
0 Z 1000 24589 1 0 80 0 - 0 exit ? 00:00:00 soffice.bin <defunct>
(왼쪽의 "Z"참고)
5 번째 열이 1이 아니면 상위 프로세스가 있음을 의미합니다. 해당 부모 프로세스 id를 강제 종료하십시오 .
만약 PPID가 1이라면, 그것을 죽이지 마라 !! 다른 기기 나 프로세스와 관련이있을 수 있습니다.
예를 들어, 마운트 된 장치 또는 Samba를 사용중인 경우 마운트 해제하십시오. 좀비 프로세스가 해제 될 수 있습니다.
참고 : ps -Al
(또는 top
)에 "Z"대신 "D"가 표시되면 원격 마운트 (NFS와 같은)와 관련이있을 수 있습니다. 내 경험에 따르면 재부팅하는 것이 유일한 방법이지만 해당 사례를 자세히 다루는 다른 답변을 확인할 수 있습니다.
다른 사람들이 언급했듯이, 무정전 수면 과정은 즉시 (또는 경우에 따라) 죽일 수 없습니다. 특정 프로세스, 특히 프로세스가 NFS를 기다리는 일반적인 경우에이 문제를 해결하기 위해 TASK_KILLABLE이라는 다른 프로세스 상태가 추가되었다는 점은 주목할 가치가 있습니다. http://lwn.net/Articles/288056/을 참조 하십시오
불행히도 이것이 커널의 어느 곳에서나 NFS가 아니라고 생각합니다.
ls
액세스 하는 프로세스를 종료 하는 데 문제가있었습니다 sshfs
. 이러한 상황을 피하기 위해 나중에 사용할 수있는 FUSE 또는 sshfs에 대한 솔루션이 있습니까? 2.6.30 커널
좀 더 살펴볼 수 있도록 작은 스크립트를 만들었습니다!
이것을 사용하여 경로에 주어진 이름을 가진 프로세스를 죽일 수 있습니다 (주의하십시오!) 또는 "-u username"매개 변수를 사용하여 주어진 사용자의 프로세스를 죽일 수 있습니다.
#!/bin/bash
if [ "$1" == "-u" ] ; then\n
PID=`grep "$2" /etc/passwd | cut -d ":" -f3`
processes=`ps aux | grep "$PID" | egrep -v "PID|ps \-au|killbyname|grep" | awk '{ print $2}'`
echo "############# Killing all processes of user: $2 ############################"
else
echo "############# Killing processes by name: $1 ############################"
processes=`ps aux | grep "$1" | egrep -v "killbyname|grep" | awk '{ print $2}' `
fi
for process in $processes ; do
# "command" stores the entire commandline of the process that will be killed
#it may be useful to show it but in some cases it is counter-productive
#command=`ps aux | grep $process | egrep -v "grep" | awk '{ print $2 }'`
echo "Killing process: $process"
echo ""
kill -9 $process
done
나는 이런 종류의 문제가 있었다. 이것은 내가 시작 strace
하고 Ctrl
+로 중단 한 프로그램이었습니다 C
. 결국 T
(추적 또는 중지) 상태가되었습니다. 나는 그것이 어떻게 일어 났는지 모르겠지만,로 살해 할 수 없었습니다 SIGKILL
.
간단히 말해, 나는 그것을 죽이는 데 성공했습니다 gdb
:
gdb -p <PID>
> kill
Kill the program being debugged? (y or n) y
> quit
gilles의 대답에 대한 단서를 기반으로 <defunct>
시스템 리소스를 사용하는 상단에 "Z"라고 표시된 프로세스 가 있고, 청취 중이었던 포트가 열려있어 해당 포트에 연결할 수 있습니다. 이것은에 대한 실행 후였습니다 kill -9
. 그것의 부모는 "1"(즉 init
)이므로 이론적으로 그냥 반복해서 사라져야합니다. 그러나 그렇지는 않았지만 달리지 않고 "죽지 않았다"
제 경우에는 좀비이지만 여전히 리소스를 소비합니다 ... FWIW.
그리고 그것은 임의의 수에 의해 killable하지 않았다 kill -9
'의
그리고 부모는 init
있었지만 거두지 않았습니다. 즉 init
, 좀비 아이가있었습니다.
그리고 문제를 해결하기 위해 재부팅 할 필요가 없었습니다. 재부팅으로 문제가 해결되었지만 더 빨리 종료되었습니다. 우아하지는 않았지만 여전히 가능했습니다.
그리고 좀비 프로세스가 소유 한 LISTEN 포트였습니다 (로컬 호스트에 로컬 호스트에 연결된 CLOSE_WAIT 상태와 같은 다른 포트도 있습니다). 그리고 그것은 여전히 연결을 받아 들였습니다. 좀비로도. 포트를 정리하지는 않았지만 들어오는 연결은 여전히 TCP 수신 포트의 백 로그에 추가되었지만 허용 될 가능성은 없었습니다.
위의 많은 것들이 웹의 여러 곳에서 "불가능"하다고 언급되어 있습니다.
내부에 스레드가있어 "시스템 호출"(이 인스턴스에서는 ioctl)을 실행하는 데 몇 시간이 걸렸습니다 (예상 동작이었습니다). 분명히 시스템은 ioctl
호출 에서 돌아올 때까지 프로세스를 "종료"종료 할 수 없습니다 . 커널 랜드로 들어가는 것 같습니다. 몇 시간이 지난 후, 물건이 치워지고 소켓이 예상대로 모두 자동으로 닫혔습니다. 그것은 죽음의 행에 약간의 고통스러운 시간입니다! 커널은 참을성있게 죽이기를 기다리고있었습니다.
따라서 OP에 응답하려면 때로는 기다려야합니다. 오랜만이야 그러면 죽일 것이다.
또한 dmesg를 검사하여 커널 패닉 (예 : 커널 버그)이 있는지 확인하십시오.