부모 프로세스가 모든 자식 프로세스가 종료될 때까지 기다리도록 강제할 수 있는 방법이 없다는 것을 알고 있습니다. 그러나 이것은 다음과 같은 규칙입니다. 또한 자식 프로세스가 종료되기 전에 부모 프로세스가 종료되면 자식 프로세스는 고아 프로세스가 되어내부에프로세스. 그러나 내가 이해하지 못하는 것은 하위 프로세스가 고아가 되어 하위 프로세스에 의해 채택되면 문제가 무엇입니까?내부에프로세스. 종료될 때까지 상위 프로세스 자체에 연결되어야 하는 이유는 무엇입니까?
답변1
이 규칙의 주된 이유는 프로세스가 하위 프로세스를 분기하는 경우 일반적으로 하위 프로세스가 실행된다는 것입니다.기본 프로세스에서 수행할 것으로 예상되는 작업의 일부입니다. 포크로 간주되는 프로그램의 예가 있습니까?
여기 몇 가지 예가 있어요.
- 집중적인 계산을 수행하는 프로그램은 여러 CPU/코어에서 동시에 실행하기 위해 자신의 여러 복사본을 포크할 수 있습니다. (이를 위해 스레드를 사용하는 것이 아마도 더 전통적일 수 있지만 확실히 프로세스를 포크하여 수행할 수 있습니다.) 이와 같은 프로그램가능한프로세스당 단일 출력만 작성하도록 설계되었습니다. 그러나 기본 프로세스가 모든 하위 프로세스가 완료될 때까지 기다린 다음 결과를 병합하는 것도 일반적입니다.
- 이와 같은 프로그램에는
netcat
호스트 A에서 읽고 호스트 B에 쓰는 하나의 프로세스와 호스트 B에서 읽고 호스트 A에 쓰는 또 다른 프로세스가 있는 경우가 있습니다. (물론 쓰레드로도 가능합니다.) find -exec
즉, 및 의 경우xargs
(메인) 프로그램의 작업은 슬레이브 프로그램을 실행하는 것입니다. 완료될 때까지 기다리세요. 사용자가 다음과 같이 말하면 어떻게 될지 상상해 보세요.찾다. -type f -exec cp {} /backup';' && rm -r .
find
모든 복사가 완료될 때까지 기다리지 않고 종료합니다 .
이러한 경우(및 기타 경우)에는 모든 하위 프로세스가 완료될 때까지 기본 프로그램의 작업이 완료되지 않습니다. 따라서 프로그램은 모든 하위 프로세스를 기다리기 전에 종료되어서는 안 됩니다.
물론 이것이 포크를 사용할 수 있는 유일한 방법은 아닙니다. 네트워크 서버(예: FTP 및 메일)에는 일반적으로 들어오는 연결을 수신하고 클라이언트 연결이 이루어질 때마다 하위 프로세스를 분기하는 기본 프로세스가 있습니다. 이러한 하위 프로세스는 언제든지(클라이언트가 결정) 종료될 수 있으며 기본 프로세스는 하위 프로세스를 기다릴 이유가 없습니다.
하위 프로세스가 종료될 때 어떤 "상위"/리퍼 프로세스와 연관되는지에 대한 정보는 실제로 문제가 되지 않습니다.
답변2
이 규칙의 주된 이유는 상위 프로세스가 하위 프로세스보다 먼저 종료되면 하위 프로세스의 종료 코드가 손실되고 하위 프로세스가 한동안 좀비 상태로 남아 있을 수 있다는 것입니다.
하위 프로세스가 종료된 후 종료 코드를 읽을 때까지 남아 있고 메모리를 소비합니다. 이것은 좀비 프로세스라고 불리는 것입니다. 즉, 죽었으나 수확(제거)되지는 않습니다.
일반적으로 종료 코드를 읽고 좀비 프로세스가 완전히 사라지도록 허용하는 것은 상위 프로세스의 책임입니다. 부모는 자녀를 계속 추적해야 하므로 이 문제가 빨리 해결되기를 바랍니다. 상위 프로세스가 이를 수행하지 않으면 리소스 누수가 발생합니다.
상위 프로세스가 하위 프로세스보다 먼저 종료되면 init가 해당 책임을 인수하지만 이를 즉시 인식하지 못할 수 있으므로 하위 프로세스는 더 오랫동안 좀비로 남아 더 많은 리소스를 차지할 수 있습니다.
편집: 명확히 하기 위해 좀비 상태의 프로세스는 모든 메모리를 유지하지 않습니다. 프로세스가 좀비가 되기 전에 대부분의 메모리가 해제됩니다. 이는 프로세스 테이블에 유지된 항목입니다. 프로세스 테이블 항목이 많을수록 커널이 프로세스 관련 활동을 수행하는 데 더 많은 시간이 걸립니다.