Я пишу bash-скрипт, который порождает несколько фоновых процессов.Я хотел бы получать уведомления всякий раз, когда процесс завершается;и я хотел бы знать pid завершенного процесса.
Я рассмотрел использование wait
, чтобы pids каждого порожденного процесса захватывался и сохранялся в массиве, а затем массив перебирался, и ожидание вызывалось для каждого процесса.Этот метод описывается здесь по-разному:
https://stackoverflow.com/a/356154/366856
Проблема с этим, если я правильно понимаю, заключается в том, что она может быть относительно неэффективной, если вы хотите выполнить какое-либо действие, каккак только отдельный процесс заканчивается.Например, если вы порождаете процессы A и B, а B завершается раньше, чем A, то выполнение должно ждать, пока завершатся и A, и B.Мне нужно выполнить действие, как только закончится B.
Кажется, trap SIGCHLD
- это способ выполнить действие сразу после завершения дочернего процесса, но проблема в том, что я не могу найти способ определить pidисточника сигнала SIGCHLD, который мне тоже нужен.Наиболее близкий момент, который я нашел к рабочему примеру этого, - третий пример кода в этом посте:
http://www.linuxforums.org/forum/programming-scripting/103996-multithreading-bash.html#post510187
Я скопировал его сюда для удобства:
#!/bin/bash
iNext=0
function ChildReturned() {
wait $1
echo "$1 was returned. Its exits status was: $?"
iNext=$((iNext+1))
StartChild $iNext
}
function StartChild {
./child $1 &
pid=$!
echo "Started: $1 PID= $pid"
trap 'ChildReturned $pid' SIGCHLD
}
set -bm
for (( iNext=0; iNext<=10; iNext++ ));
do
StartChild $iNext
done
wait
Я думаю, что этот пример не работает, потому что автор делает ошибку, вызывая trap
несколько раз, каждый раз захватывая другую переменную pid в аргументе trap
.Каждый раз, когда вызывается trap, он перезаписывает предыдущий вызов, и, таким образом, произвольный pid будет захвачен.Мне не удалось найти лучшую технику.
Есть ли способ получить pid завершенного дочернего процесса, используя trap в bash?
Обновление
Я просто хотел указать на этот ресурс, который содержит лучший, наиболее полный обзор решений этой проблемы, которые я видел до сих пор:
http://mywiki.wooledge.org/ProcessManagement#I_want_to_process_a_bunch_of_files_in_parallel.2C_and_when_one_finishes.2C_I_want_to_start_the_next._And_I_want_to_make_sure_there_are_exactly_5_jobs_running_at_a_time.