나는 다른 출처를 파고 있지만 아이 수확의 해부학에 대한 좋은 설명을 찾을 수 없습니다. 이것은 내가 이해하고 싶은 간단한 사례입니다.
$ cat <( sleep 100 & wait ) &
[1] 14247
$ ps ax -O pgid | grep $$
12126 12126 S pts/17 00:00:00 bash
14248 12126 S pts/17 00:00:00 bash
14249 12126 S pts/17 00:00:00 sleep 100
14251 14250 S pts/17 00:00:00 grep --color=auto 12126
$ kill -2 14248
$ ps ax -O pgid | grep $$
12126 12126 S pts/17 00:00:00 bash
14248 12126 Z pts/17 00:00:00 [bash] <defunct>
14249 12126 S pts/17 00:00:00 sleep 100
14255 14254 S pts/17 00:00:00 grep --color=auto 12126
왜 좀비가 아이를 기다리고 있습니까?
이것을 설명 할 수 있습니까? 이것에 대한 이해를 넓히려면 C를 알고 Bash 소스 코드를 읽어야합니까? 아니면 문서가 있습니까? 나는 이미 상담했다 :
- 이 사이트의 다양한 링크 및 스택 오버플로
- W. Shotts 의 리눅스 커맨드 라인
man bash
- Bash Reference Manual (Bash 소스 코드 문서에서)
- 초보자를위한 배쉬 가이드 @ tldp.org
- 고급 배쉬 스크립팅 안내서
GNU bash, 버전 4.3.42 (1)-릴리스 (x86_64-pc-linux-gnu)
Linux 4.4.0-31-generic # 50-Ubuntu SMP 수요일 7 월 13 일 00:07:12 UTC 2016 x86_64 x86_64 x86_64 GNU / Linux
답변
좀비는 아이를 기다리지 않습니다. 다른 좀비 프로세스와 마찬가지로 부모가 수집 할 때까지 유지됩니다.
무슨 일이 일어나고 있는지 이해하기 위해 관련된 모든 프로세스를 표시하고 PPID도 살펴 봐야합니다. 이 명령 행을 사용하십시오.
ps -t $(tty) -O ppid,pgid
죽이는 프로세스의 부모는 cat
입니다. bash는 cat <( sleep 100 & wait )
서브 쉘에서 백그라운드 명령 을 실행합니다 . 이 서브 쉘이 수행하는 유일한 작업은 일부 리디렉션을 설정 한 다음 외부 명령을 실행하는 것이므로이 서브 쉘은 외부 명령으로 대체됩니다. 요약은 다음과 같습니다.
- 원래 bash (12126) 는 자식 ( 14247)
fork
에서 백그라운드 명령을 실행하기 위해 호출 합니다cat <( sleep 100 & wait )
.- 자식 (14247)
pipe
은 파이프fork
를 생성 한 다음 프로세스 대체를 실행할 자식을 생성하도록 호출 합니다sleep 100 & wait
.- 손자 (14248) 는 백그라운드에서
fork
실행되도록 호출 합니다sleep 100
. 손자는 대화식이 아니기 때문에 백그라운드 프로세스는 별도의 프로세스 그룹에서 실행되지 않습니다. 그런 다음 손자는sleep
나올 때까지 기다립니다 .
- 손자 (14248) 는 백그라운드에서
- 자식 (14247)은
setpgid
(대화식 쉘의 백그라운드 작업이므로 자체 프로세스 그룹을 가져옵니다 ) 호출 한 다음execve
실행cat
합니다. (백그라운드 프로세스 그룹에서 프로세스 대체가 일어나지 않는다는 것에 약간 놀랐습니다.)
- 자식 (14247)
- 손자를 죽입니다 (14248). 부모가 실행
cat
중이므로 자식 프로세스에 대해 아무것도 모르고 비즈니스 전화를 걸지 않습니다wait
. 손자의 부모는 그것을 거두지 않기 때문에 손자는 좀비로 남아 있습니다. - 결국,
cat
종료 –sleep
파이프 를 죽이거나 파이프를 리턴하고 닫아서cat
입력의 끝을 볼 수 있기 때문에 종료됩니다 . 이 시점에서 좀비의 부모가 죽으므로 좀비는 init에 의해 수집되고 초기화됩니다.
명령을 다음으로 변경하면
{ cat <( sleep 100 & wait ); echo done; } &
그런 다음 cat
원래 bash 프로세스의 하위가 아닌 별도의 프로세스에서 실행 echo done
됩니다. 첫 번째 하위는 실행하기 위해 남아 있어야합니다 . 이 경우 손자를 죽이면 좀비로 남아 있지 않습니다. 그 시점에서 여전히 bash를 실행하는 자식이 그것을 가져 오기 때문입니다.
참조 리눅스 핸들이 과정 좀비 않는 방법 과 좀비가 고아를 가질 수 있습니까? 고아 아이들이 좀비를 거두어 방해받을 수 있습니까?
답변
좀비는 아이를 기다리지 않습니다. 대신, 좀비는 이미 죽었거나 (예제와 같이 살해 당했음), 코드, 데이터 및 스택 할당이 해제 된 프로세스이며 이제 종료 코드 만 포함되어 부모가 호출 wait(2)
하기 를 기다 립니다. (따라서 마지막으로 프로세스 테이블에서 프로세스 항목을 완전히 정리하십시오)
귀하의 예에서 수면이 끝나면 (또는 사망) 부모는 종료 상태를 읽고 좀비를 수확합니다. 자세한 내용은 위에서 언급 한 내용을 참조 wait(2)
하십시오.