다양한 출처를 조사하고 있지만 어린이 수확의 해부학적 구조에 대한 좋은 설명을 찾을 수 없습니다. 이것은 제가 이해하고 싶은 간단한 사례입니다.
$ 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 소스 코드를 읽어야 합니까? 아니면 문서가 있습니까? 내가 상담한 내용:
- 이 사이트와 Stack Overflow의 다양한 링크
- 리눅스 명령줄저자: W. Shortz
man bash
- Bash 참조 매뉴얼(Bash 소스 코드 문서에 있음)
- Bash 초보자 가이드@tldp.org
- 고급 Bash 스크립팅 가이드
GNU bash, 버전 4.3.42(1)-릴리스(x86_64-pc-linux-gnu)
Linux 4.4.0-31-일반 #50-Ubuntu SMP Wed Jul 13 00:07:12 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
답변1
좀비에게는 그것을 기다리는 아이들이 없습니다. 다른 좀비 프로세스와 마찬가지로 상위 프로세스가 이를 수집할 때까지 존재합니다.
무슨 일이 일어나고 있는지 이해하고 PPID를 확인하려면 관련된 모든 프로세스를 표시해야 합니다. 다음 명령줄을 사용하세요.
ps -t $(tty) -O ppid,pgid
종료하려는 프로세스의 상위 프로세스는 입니다 cat
. bash는 cat <( sleep 100 & wait )
하위 쉘에서 백그라운드 명령을 실행합니다. 서브셸이 수행하는 유일한 작업은 일부 리디렉션을 설정한 다음 외부 명령을 실행하는 것이므로 서브셸은 외부 명령으로 대체됩니다. 요약은 다음과 같습니다.
- 원래 bash(12126) 호출은 하위 프로세스(14247)에서 백그라운드 명령을 실행합니다
fork
.cat <( sleep 100 & wait )
- Subprocess(14247)는
pipe
파이프를 생성한 후fork
프로세스 교체를 실행하기 위한 하위 프로세스를 생성하기 위해 호출됩니다sleep 100 & wait
.- Sun Tzu(14248)는 백그라운드
fork
실행을 호출합니다.sleep 100
손자 프로세스는 대화형이 아니기 때문에 백그라운드 프로세스는 별도의 프로세스 그룹에서 실행되지 않습니다. 그런 다음 손자가sleep
나가기를 기다리고 있습니다.
- Sun Tzu(14248)는 백그라운드
- subprocess(14247)이 호출된
setpgid
후(대화형 셸의 백그라운드 작업이므로 자체 프로세스 그룹이 있음)execve
실행됩니다cat
(백그라운드 프로세스 그룹에서 프로세스 교체가 발생하지 않는다는 사실에 조금 놀랐습니다.)
- Subprocess(14247)는
- 당신은 손자를 죽였습니다 (14248). 상위 프로세스가 실행 중이고
cat
하위 프로세스에 대해 아무것도 모르고 비즈니스 호출도 없습니다wait
. 손자의 부모가 수확을 하지 않아 손자는 좀비처럼 남겨진다. - 결국, 그것은 종료됩니다 - 당신이 그것을 죽였거나 파이프를 반환하고 닫아서 입력의 끝을 보았
cat
기 때문입니다 . 이 시점에서 좀비의 부모 프로세스는 종료되므로 좀비는 그것을 얻는 init에 의해 수집됩니다.sleep
cat
명령을 다음으로 변경하면
{ cat <( sleep 100 & wait ); echo done; } &
그런 다음 cat
원래 bash 프로세스의 하위 프로세스가 아닌 별도의 프로세스에서 실행됩니다. 첫 번째 하위 프로세스는 계속 실행 중이어야 합니다 echo done
. 이 경우 손자를 죽이면 (이 시점에서 여전히 bash를 실행 중인) 자식이 손자를 수확하기 때문에 좀비로 계속되지 않습니다.
당신은 또한 볼 수 있습니다Linux에서 좀비 프로세스를 처리하는 방법그리고좀비에게 고아가 있을 수 있나요? 고아들은 좀비를 수확하는 것에 대해 화를 낼까요?
답변2
좀비는 아이들을 기다리고 있지 않습니다. 대신 좀비는이것(예에서와 같이 자체적으로 또는 종료된) 프로세스는 해당 코드, 데이터 및 스택을 해제했으며 이제는 종료 코드만 포함하고 해당 프로세스를 wait(2)
검색하기 위해 상위 호출을 기다리고 있습니다. 결국 프로세스 테이블에서 프로세스 항목을 완전히 정리합니다.)
귀하의 예에서 수면이 완료되거나 종료되면 부모는 종료 상태를 읽고 좀비를 수확합니다. wait(2)
자세한 내용은 위를 참조하세요.