부모가 init 인 <defunct> 프로세스를 어떻게 죽일 수 있습니까?


27

NAS에서 전송이 간헐적으로 중단됩니다. SIGTERM을 보내면 프로세스 목록에서 사라지지 않고 <defunct>그 옆에 레이블이 나타납니다. SIGKILL을 보내도 여전히 사라지지 않고 부모가이므로 부모를 종료 할 수 없습니다 init. 프로세스를 제거하고 전송을 다시 시작할 수있는 유일한 방법은 재부팅입니다.

내가 할 수있는 최선의 방법은 Transmission을 시도하고 수정하는 것입니다 (그리고 시도했습니다). 그러나 나는 컴파일하는 초보자이며 토런트가 끝나기 전에 토런트를 끝내고 싶었습니다.


3
"init"가 소유 한 <defunct> 프로세스는 불가능할 것입니다. 이것은 매우 이상한 상황입니다! 확실합니까?
JoelFan

@JoelFan : 중요한 것을 잊고 있지 않은지 확인하기 위해 찾고있었습니다. 아이들의 좀비 는 많은 일반적인 작업 중 하나로서 아이들을 주기적으로 기다린 init후 꽤 빨리 사라져야합니다. 좀비와 동일합니까? init<defunct>
D.Shawley

1
nevermind ... <defunct>은 좀비와 정확히 동일합니다. init아이들을 기다릴 것이므로 이론 상으로는 절대 일어나지 않아야합니다. 를 보내면 어떻게되는지 궁금 SIGCHLD합니다 init.
D.Shawley

@JoelFan : 예, 확실합니다. PPID의 값은 1 (초기)이므로 프로세스를 SIGKILL하는 것이 불가능했습니다.
Andy E

답변:


35

<defunct>프로세스가 이미 종료되었으므로 프로세스 (좀비 프로세스라고도 함)를 종료 할 수 없습니다 . 시스템은 부모가 종료 상태를 수집 할 수 있도록 좀비 프로세스를 유지합니다. 부모가 종료 상태를 수집하지 않으면 좀비 프로세스가 영원히 유지됩니다. 좀비 프로세스를 제거하는 유일한 방법은 부모를 죽이는 것입니다. 부모가 초기화되면 재부팅 만 할 수 있습니다.

좀비 프로세스는 리소스를 거의 차지하지 않으므로 성능을 유지하는 데 비용이 들지 않습니다. 좀비 프로세스가 주변에 있다는 것은 일반적으로 일부 프로그램에 버그가 있음을 의미합니다. Init은 일반적으로 모든 어린이를 수집해야합니다. init에 좀비 자식이 있으면 init에 버그가 있습니다 (또는 다른 버그가 있습니다).

http://en.wikipedia.org/wiki/Zombie_process


9
init좀비 어린이를 가질 수 없습니다. 위키피디아 기사에서 : 프로세스가 부모를 잃으면 init는 새로운 부모가됩니다. Init은 주기적으로 대기 시스템 호출을 실행하여 init를 부모로하여 좀비를 거둔다. init의 책임 중 하나는 고아와 부모없는 좀비를 거두는 것입니다.
D.Shawley

14
@ D.Shawley : init버그가있을 수 있습니다. 초기화 교체 runit에는이 문제를 일으키는 버그가 있습니다.
camh

2
init는 버그로 인해 기능이 상실된 자식을 가질 수 있지만 가능합니다. 지금보고있는 것이기 때문입니다.
studgeek

이 프로그램은 터미널에서 실행되어 기능 상실 상태로 들어갔습니다. @lesmana의 설명에 따라 터미널 (부모)을 닫으면 프로그램이 깨끗하게 종료됩니다.
mk ..

6

피하기 좀비와 시그널 핸들러에 "이중 포크"트릭에 대해 읽어야 전송 C 소스 코드를 해결하기 위해 노력 누구 ... 어떻게이 스마트 가변 스폰 기능의 일부로 사용할 수있다 (참조 : 유닉스에서 산란을 ).

excerpt from: 
   "Spawning in Unix", http://lubutu.com/code/spawning-in-unix

Double fork
This trick lets you spawn processes whilst avoiding zombies, without 
installing any signal handler. The first process forks and waits for its 
child; the second process forks and immediately exits and is reaped;
the third process is adopted by init, and executes the desired program. 
All zombies accounted for, since init is always waiting.

if(fork() == 0) {
   if(fork() == 0) {
       execvp(file, argv);
       exit(EXIT_FAILURE);
   }
   exit(EXIT_SUCCESS);
}
wait(NULL);

1
이중 포크는 커널이 상위를 PID 1로 설정하여 좀비를 정리하여 좀비 프로세스를 방지합니다. 부모가 이미 프로세스 1이기 때문에 Transmission이 이미 수행하는 것처럼 들립니다.
Jander

1
여기에는 여러 가지 문제가 있습니다. # 1 : 부모 만 전화해야합니다 exit(3). 아이들은 _exit(2)대신 전화해야 합니다 (그렇지 않으면 다른 문제 중에서 여러 stdio 플러시를 얻습니다). # 2 : 실패하면 execvp(3)사용할 수 있습니다 perror(3). # 3 : signal(SIGCHLD, SIG_IGN)이 엉망진창 대신 사용해야 합니다.
케빈
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.