Короткий ответ
Orphan-процесс — процесс, родитель которого завершился раньше него; операционная система автоматически переназначает такому процессу нового родителя — как правило, процесс инициализации (systemd с PID 1 или специально выделенный subreaper), который затем обязан вызывать wait() для освобождения завершившихся осиротевших процессов.
Как это работает подробнее
Когда родительский процесс завершается, пока у него ещё есть живые дочерние процессы, ядро репарентит (reparent) их на init (PID 1) или на ближайший процесс-предок, помеченный флагом PR_SET_CHILD_SUBREAPER (это умеют делать системы управления процессами вроде systemd, tini, s6); именно поэтому init обязательно должен уметь обрабатывать wait() для чужих детей, иначе они превратятся в зомби без возможности когда-либо быть «собранными».
Пример кода
docker run --init myimage
# или в Dockerfile:
# ENTRYPOINT ["tini", "--", "myapp"]Что использовать на практике
- Практика. проблема особенно актуальна в контейнерах: если в контейнере PID 1 — это само приложение, а не init-подобный процесс, оно может не вызывать wait() для осиротевших дочерних процессов, и зомби будут накапливаться; поэтому для сложных приложений, порождающих дочерние процессы, в контейнер часто добавляют лёгкий init-процесс (tini, dumb-init).
Подводные камни
- Риск. Частая ошибка — запускать в контейнере сложное приложение-оркестратор дочерних процессов напрямую как PID 1 без init-обёртки и удивляться накоплению зомби-процессов внутри долгоживущего контейнера.