Вчера написал простенькую, но (для меня) уже вполне функциональную запускалку задач из bash-скриптов. Её предназначение простое: брать из стандартного потока ввода текст задачи (на том же bash) и запускать её «в фоне». Отличие от простого «амперсанда» простое, но существенное: количество одновременно запущенных таким образом задач должно быть меньше или равно количеству процессорных ядер. Если требуется запустить задачу тогда, когда все ядра уже заняты ранее запущенными ones, моя функция будет ждать освобождения хотя бы одного из ядер.
Собственно, актуальный текст данной функции можно будет всегда найти на github'е (https://github.com/DRVTiny/bash4-debug-infra), а сюда скопирую текущую версию просто для того, чтобы было понятно, о чём речь и как э
то реализовано.
Если есть идеи, как реализовать чистку списка запущенных задач без дорогостоящего полинга - с использованием какого-нибудь SIGCHLD, например, - буду очень признателен.
declare -i CPU_KERNELS=$(fgrep processor /proc/cpuinfo | wc -l)
declare -A TASKS_QUEUE=()
unset wait4_cpu_free push_task
rotate_tq () {
 declare -i taskPID flTaskGone=0
 for taskPID in ${!TASKS_QUEUE[@]}; do
  [[ -f /proc/$taskPID/cmdline && ${TASKS_QUEUE[$taskPID]} == "$(</proc/$taskPID/cmdline)" ]] 2>/dev/null || {
   flTaskGone=1
   unset TASKS_QUEUE[$taskPID]
  }
 done
 return $flTaskGone
}
wait4_cpu_free () {
 while :; do
  rotate_tq || break
 done
 return 0
}
push_task () {
 local taskPID
 if (( ${#TASKS_QUEUE[@]} )); then
  rotate_tq
  (( ${#TASKS_QUEUE[@]} >= CPU_KERNELS )) && wait4_cpu_free
 fi
 eval "$(cat -)" &
 taskPID=$!
 [[ -f /proc/$taskPID/cmdline ]] && \
  TASKS_QUEUE[$taskPID]="$(</proc/$taskPID/cmdline)"
 return $?
}








