Становится ли PID дочернего процесса доступным для повторного использования, если родительский процесс все еще выполняется?

Я работаю на ОС *nix и у меня есть скрипт, который запускает несколько процессов одновременно. Для меня главная цель - запустить эти процессы одновременно и собрать возвращенные состояния выхода для каждого из процессов. Я обнаружил, что с помощью wait(pid) достигнет этого, так как все дочерние процессы принадлежат родительскому процессу. Тем не менее, я обеспокоен тем, что после завершения дочернего процесса (один из запущенных параллельных процессов) его PID будет выпущен и доступен для повторного использования в системе.

Таким образом, я предполагаю, что вопрос в том, что если родительский процесс инициирует несколько дочерних процессов одновременно, будет ли PID доступного завершенного дочернего процесса доступен системе для повторного использования до завершения родительского процесса? Если так, как я могу лучше всего получить статусы выхода каждого из дочерних процессов?

Пример скрипта bash ниже:

local file=$1
local count=0
<files are split; and suffixed with aa,ab,ac,ad>

/home/text/concurrencyTest.sh $file-aa >> /home/text/$file-aa.log 2>&1 &
/home/text/concurrencyTest1.sh $file-ab >> /home/text/$file-ab.log 2>&1 &
/home/text/concurrencyTest2.sh $file-ac >> /home/text/$file-ac.log 2>&1 &
/home/text/concurrencyTest3.sh $file-ad >> /home/text/$file-ad.log 2>&1 &

for job in `jobs -p`
do
    echo "Job: $job"
    wait "$job"
    rc=$?
    echo "RC for $job is $rc"
    if [[ rc -ne 0 ]]; then
        FAIL[$count]="$job"
        ((count++))
    fi
done
if [[ $count -ne 0 ]]; then
    echo "ERROR: $count Job(s) Failed!"
    echo "Failed Process PID(s): ${FAIL[@]}"
    echo "Failed Processing for file: $file"
    return 1
fi

1 ответ

Решение

PID дочернего процесса становится доступным для повторного использования, когда родительский процесс вызывает wait или же waitpid (или любая другая функция этой семьи, такая как wait3, wait4, так далее.).

Когда ребенок умирает, он остается зомби - запись в таблице процессов, за которой нет процесса, которая остается только для того, чтобы зарезервировать идентификатор процесса и сохранить статус выхода. призвание waitpid блокируется до тех пор, пока указанный дочерний процесс не умрет (или немедленно вернется, если он уже мертв), извлечет код состояния дочернего процесса и пожнет зомби (то есть удалит запись таблицы процессов, освобождая идентификатор процесса для повторного использования). призвание wait похоже, но возвращается, как только один дочерний процесс умер.

Если родительский процесс игнорирует SIGCHLD Сигнал в тот момент, когда процесс умирает, затем процесс не превращается в зомби, и его PID становится доступным для повторного использования немедленно. Статус родителя по отношению к SIGCHLD имеет иное значение; см., например, POSIX для получения подробной информации.

Если родительский процесс умирает раньше ребенка, говорят, что ребенок является сиротой, усыновленным init, процесс с PID 1. Это часть работы init, чтобы пожинать сирот.

В сценарии оболочки wait Встроенный это обертка вокруг wait системный вызов. Если сценарий имеет несколько детей, wait без блоков аргументов, пока все они не умерли, и wait с некоторыми аргументами блокирует до тех пор, пока все указанные процессы не прекратятся (невозможно дождаться, пока один процесс не прекратит работу, не указав, какой именно) Если wait $pid1 возвращается, возможно, что $pid2 уже умер и был повторно использован для другого процесса; однако оболочка отслеживает $pid2код состояния даже так, и последующий wait $pid2 вернет свой код состояния. Вы не должны раскошелиться на новую фоновую работу до тех пор, однако, чтобы избежать путаницы в случае $pid2 был повторно использован для фоновой работы.

Другие вопросы по тегам