यहां पार्टी के लिए वास्तव में देर हो चुकी है, लेकिन यहां एक और समाधान है।
बहुत सारे समाधान आदेशों में रिक्त स्थान / विशेष पात्रों को नहीं संभालते हैं, हर समय एन नौकरियों को चालू नहीं रखते हैं, व्यस्त छोरों में सीपीयू खाते हैं, या बाहरी निर्भरता (जैसे जीएनयू parallel) पर भरोसा करते हैं ।
मृत / ज़ोंबी प्रक्रिया से निपटने के लिए प्रेरणा के साथ , यहाँ एक शुद्ध बैश समाधान है:
function run_parallel_jobs {
local concurrent_max=$1
local callback=$2
local cmds=("${@:3}")
local jobs=( )
while [[ "${#cmds[@]}" -gt 0 ]] || [[ "${#jobs[@]}" -gt 0 ]]; do
while [[ "${#jobs[@]}" -lt $concurrent_max ]] && [[ "${#cmds[@]}" -gt 0 ]]; do
local cmd="${cmds[0]}"
cmds=("${cmds[@]:1}")
bash -c "$cmd" &
jobs+=($!)
done
local job="${jobs[0]}"
jobs=("${jobs[@]:1}")
local state="$(ps -p $job -o state= 2>/dev/null)"
if [[ "$state" == "D" ]] || [[ "$state" == "Z" ]]; then
$callback $job
else
wait $job
$callback $job $?
fi
done
}
और नमूना उपयोग:
function job_done {
if [[ $# -lt 2 ]]; then
echo "PID $1 died unexpectedly"
else
echo "PID $1 exited $2"
fi
}
cmds=( \
"echo 1; sleep 1; exit 1" \
"echo 2; sleep 2; exit 2" \
"echo 3; sleep 3; exit 3" \
"echo 4; sleep 4; exit 4" \
"echo 5; sleep 5; exit 5" \
)
cpus=3
run_parallel_jobs $cpus "job_done" "${cmds[@]}"
उत्पादन:
1
2
3
PID 56712 exited 1
4
PID 56713 exited 2
5
PID 56714 exited 3
PID 56720 exited 4
PID 56724 exited 5
प्रति-प्रक्रिया आउटपुट हैंडलिंग के $$लिए फ़ाइल में लॉग इन करने के लिए इस्तेमाल किया जा सकता है, उदाहरण के लिए:
function job_done {
cat "$1.log"
}
cmds=( \
"echo 1 \$\$ >\$\$.log" \
"echo 2 \$\$ >\$\$.log" \
)
run_parallel_jobs 2 "job_done" "${cmds[@]}"
आउटपुट:
1 56871
2 56872