ProgramingTip

Linux에서 프로세스에 대해 kill -9가 효과가있는 것이 어떻게 가능합니까?

bestdevel 2020. 11. 20. 09:18
반응형

Linux에서 프로세스에 대해 kill -9가 효과가있는 것이 어떻게 가능합니까?


웹 사이트를 방문 할 때 텍스트를 자동으로 강조 표시하는 것이 좋습니다. 하이라이트 검색 결과와 충돌하지만 자동으로 많은 단어에 대해 표시됩니다. 예를 들어 음식 사이트를 검색 할 때 돋보이게 만드는 데 사용할 수 있습니다.

하지만 문제가 있습니다. 비어있는 새 FF 창을 닫으려고하면 어떻게 든 전체 프로세스를 차단합니다. 프로세스를 종료하면 모든 창이 사라지지만 Firefox 프로세스는 살아 있습니다. (부모 PID는 1이고, 어떤 것도 듣지 않고, 많은 리소스가 있고, 여전히 CPU를 먹지만 움직이지 않습니다.)

두 가지 질문이 있습니다.

  1. -9 (사용자 또는 루트가 아님)를 수신하지 않는 것이 어떻게 처리 할 수 ​​있습니까?

  2. 그 외에 할 수있는 일이 있습니까?

[편집] 잘못된 프로세스입니다.

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
digulla  16688  4.3  4.2 784476 345464 pts/14  D    Mar28  75:02 /opt/firefox-3.0/firefox-bin

와 같다 ps -ef | grep firefox

UID        PID  PPID  C STIME TTY          TIME CMD
digulla  16688     1  4 Mar28 pts/14   01:15:02 /opt/firefox-3.0/firefox-bin

남은 유일한 과정입니다. 보시다시피 좀비가 아니라 달리고 있습니다! 내가 PID 또는 이름으로 죽여도 kill -9를 듣지 언어! 와 연결을 시도 strace하면 strace도 중단되고 죽일 수 없습니다. 출력도 없습니다. 내 생각에 FF는 일부 선택 루틴에서 중단 어느 것입니까?

[EDIT2] sigjuice의을 기반으로 :

ps axopid,comm,wchan

프로세스가 중단 된 루틴을 보여줄 수 있습니다. 필자의 경우 문제가있는 플러그인은 Beagle Indexer (openSUSE 11.1)였습니다. 더 빠르고 한 후 FF는 다시 빠르고 행복한 여우가되었습니다.


OP에 대한 설명에서 언급했듯이 프로세스 상태 ( STAT) D는 프로세스가 "무정전 보강"상태 있음을 나타냅니다. 실제 용어로 일반적으로 I / O를 완료 될 때까지 I / O 작업이 완료 될 때까지 죽는 것을 포함하여 아무것도 할 수 없습니다.

D상태의 프로세스 는 일반적으로 작업이 완료되고 R/로 돌아 오기 전에 몇 초 동안 만 존재합니다 S. 내 경험상 프로세스가 막히면 , 강력한 D수없는 NFS 또는 다른 원격 파일 시스템과 통신하거나, 고장난 하드 드라이브에 액세스하거나 비정상적인 장치 드라이버를 통해 일부 하드웨어를 사용하려고 시도하는 경우를 통해 일부 하드웨어를 사용하려고합니다. fs / 드라이브 / 하드웨어를 백업하고 실행하여 I / O를 완료하거나 시스템을 포기하고 제거하는 것입니다. NFS의 특정 경우에는 마운트가 결국 시간 초과되어 I / O 작업에서 반환 될 수 있습니다 (실패 코드 포함) 마운트 옵션에 따라 다르며 NFS 마운트가 영원히 대기하도록 설정하는 것이 매우 일반적입니다. .

이 상태가 인 좀비 프로세스와 추가 Z.


parent-id가 실제로 1인지 다시 확인하십시오. 그렇지 않은 경우 먼저 firefox시도하십시오 sudo killall -9 firefox-bin. 그 후 .NET을 사용하여 특정 프로세스 ID를 식별하십시오 sudo killall -9 [process-id].

프로세스가 kill -9 (neiter as user 또는 root)를 수신하지 않는 것이 어떻게 할 수 있습니까?

프로세스가 사라진 <defunct>다음 부모가 1 인 좀비 가면 수동으로 죽일 수 없습니다. 오직 init할 수 있습니다. 좀비 프로세스는 이미 죽었다. 그들은 더 이상 프로세스가 아니기 때문에 죽을 수있는 능력을 잃었습니다. 단지 프로세스 테이블 항목과 관련 종료 코드만이 수집되기를 기다리고 있습니다. 를 죽여야하고 부모 init명백한 이유로 죽일 수 없습니다 .

그러나 더 일반적인 정보는 여기참조 하십시오 . 자연스럽게 모든 것을 죽일 것입니다.


이 프로세스를 종료 할 때 (예 : init에 의해) 다시 시작할 수 있습니까?

쉽게 확인할 수 있습니다. PID가 kill -9 PID다시 시작되지 않은 경우 프로세스가 종료되지 않습니다.


나는 최근에 Double Fork 의 함정에 갇혀 마침내 내 대답을 찾기 전에이 페이지에 도착했습니다. 증상은 동일하지 않습니다.

  • WYKINWYT : 당신이 죽인 것은 당신이 생각한 것이 아닙니다

최소 테스트 코드는 SNMP 데몬의 예를 기반으로 아래에 나와 있습니다.

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

int main(int argc, char* argv[])
{
    //We omit the -f option (do not Fork) to reproduce the problem
    char * options[]={"/usr/local/sbin/snmpd",/*"-f","*/-d","--master=agentx", "-Dagentx","--agentXSocket=tcp:localhost:1706",  "udp:10161", (char*) NULL};

    pid_t pid = fork();
    if ( 0 > pid ) return -1;

    switch(pid)
    {
        case 0: 
        {   //Child launches SNMP daemon
            execv(options[0],options);
            exit(-2);
            break;
        }
        default: 
        {
            sleep(10); //Simulate "long" activity

            kill(pid,SIGTERM);//kill what should be child, 
                              //i.e the SNMP daemon I assume
            printf("Signal sent to %d\n",pid);

            sleep(10); //Simulate "long" operation before closing
            waitpid(pid);
            printf("SNMP should be now down\n");

            getchar();//Blocking (for observation only)
            break;
        }
    }
    printf("Bye!\n");
}

첫 번째 단계에서 메인 프로세스 (7699)는 SNMP 데몬 (7700)을 시작하지만 데몬이 이제 Defunct / Zombie 임을 알 수 있습니다 . 옆에 우리가 사용할 수있는 옵션이있는 다른 프로세스 (7702)를 볼 수 있습니다.

[nils@localhost ~]$ ps -ef | tail
root       7439      2  0 23:00 ?        00:00:00 [kworker/1:0]
root       7494      2  0 23:03 ?        00:00:00 [kworker/0:1]
root       7544      2  0 23:08 ?        00:00:00 [kworker/0:2]
root       7605      2  0 23:10 ?        00:00:00 [kworker/1:2]
root       7698    729  0 23:11 ?        00:00:00 sleep 60
nils       7699   2832  0 23:11 pts/0    00:00:00 ./main
nils       7700   7699  0 23:11 pts/0    00:00:00 [snmpd] <defunct>
nils       7702      1  0 23:11 ?        00:00:00 /usr/local/sbin/snmpd -Lo -d --master=agentx -Dagentx --agentXSocket=tcp:localhost:1706 udp:10161
nils       7727   3706  0 23:11 pts/1    00:00:00 ps -ef
nils       7728   3706  0 23:11 pts/1    00:00:00 tail

시뮬레이션 된 10 초 후에 우리가 아는 유일한 프로세스 (7700)를 종료하려고합니다. 우리가 마침내 waitpid ()로 성공한 것 . 하지만 프로세스 7702는 아직 여기에 있습니다.

[nils@localhost ~]$ ps -ef | tail
root       7431      2  0 23:00 ?        00:00:00 [kworker/u256:1]
root       7439      2  0 23:00 ?        00:00:00 [kworker/1:0]
root       7494      2  0 23:03 ?        00:00:00 [kworker/0:1]
root       7544      2  0 23:08 ?        00:00:00 [kworker/0:2]
root       7605      2  0 23:10 ?        00:00:00 [kworker/1:2]
root       7698    729  0 23:11 ?        00:00:00 sleep 60
nils       7699   2832  0 23:11 pts/0    00:00:00 ./main
nils       7702      1  0 23:11 ?        00:00:00 /usr/local/sbin/snmpd -Lo -d --master=agentx -Dagentx --agentXSocket=tcp:localhost:1706 udp:10161
nils       7751   3706  0 23:12 pts/1    00:00:00 ps -ef
nils       7752   3706  0 23:12 pts/1    00:00:00 tail

getchar () 함수에 문자를 부여한 후 주 프로세스가 종료되지만 pid 7002를 사용하는 SNMP 데몬은 여전히 ​​여기에 있습니다.

[nils@localhost ~]$ ps -ef | tail
postfix    7399   1511  0 22:58 ?        00:00:00 pickup -l -t unix -u
root       7431      2  0 23:00 ?        00:00:00 [kworker/u256:1]
root       7439      2  0 23:00 ?        00:00:00 [kworker/1:0]
root       7494      2  0 23:03 ?        00:00:00 [kworker/0:1]
root       7544      2  0 23:08 ?        00:00:00 [kworker/0:2]
root       7605      2  0 23:10 ?        00:00:00 [kworker/1:2]
root       7698    729  0 23:11 ?        00:00:00 sleep 60
nils       7702      1  0 23:11 ?        00:00:00 /usr/local/sbin/snmpd -Lo -d --master=agentx -Dagentx --agentXSocket=tcp:localhost:1706 udp:10161
nils       7765   3706  0 23:12 pts/1    00:00:00 ps -ef
nils       7766   3706  0 23:12 pts/1    00:00:00 tail

결론

우리가 이중 포크 메커니즘을 무시한 사실은 우리로 하여금 킬 액션이 성공하지 못했다고 생각하게했습니다. 그러나 사실 우리는 단순히 잘못된 프로세스를 죽였습니다!

-f 옵션 (Do Not (Double) Fork) 을 추가하면 모두 예상대로 이동합니다.


ps -ef | grep firefox; 3 개의 프로세스를 볼 수 있습니다.


sudo killall -9 firefox

작동해야

편집 : [PID]가 firefox로 변경되었습니다.


pstree를 수행하고 부모를 죽일 수도 있습니다. 이렇게하면 리프뿐만 아니라 문제가되는 전체 프로세스 트리를 얻을 수 있습니다.

참고 URL : https://stackoverflow.com/questions/694720/how-is-it-possible-that-kill-9-for-a-process-on-linux-has-no-effect

반응형