У меня есть другая перспектива ответить на это.
При работе на разных уровнях, например, в приложении MVC, контроллеру нужны службы для вызова бизнес-операций. В таких сценариях контейнер инжекции зависимостей может использоваться для инициализации служб, чтобы исключить исключение NullReferenceException. Это означает, что вам не нужно беспокоиться о проверке нулевого значения и просто вызвать службы с контроллера, как будто они всегда будут доступны (и инициализированы) как одиночный или прототип.
public class MyController
{
private ServiceA serviceA;
private ServiceB serviceB;
public MyController(ServiceA serviceA, ServiceB serviceB)
{
this.serviceA = serviceA;
this.serviceB = serviceB;
}
public void MyMethod()
{
// We don't need to check null because the dependency injection container
// injects it, provided you took care of bootstrapping it.
var someObject = serviceA.DoThis();
}
}
Это мое грубое решение:
function run_task {
cmd=$1
output=$2
concurency=$3
if [ -f ${output}.done ]; then
# experiment already run
echo "Command already run: $cmd. Found output $output"
return
fi
count=`jobs -p | wc -l`
echo "New active task #$count: $cmd > $output"
$cmd > $output && touch $output.done &
stop=$(($count >= $concurency))
while [ $stop -eq 1 ]; do
echo "Waiting for $count worker threads..."
sleep 1
count=`jobs -p | wc -l`
stop=$(($count > $concurency))
done
}
Идея состоит в том, чтобы использовать «задания», чтобы узнать, сколько детей активно в фоновом режиме и ждать, пока это число не упадет (ребенок выйдет). После того, как ребенок существует, можно запустить следующую задачу.
Как вы можете видеть, существует также немного дополнительной логики, чтобы избежать одновременного запуска одних и тех же экспериментов / команд. Он выполняет эту работу для меня. Однако эта логика может быть либо пропущена, либо улучшена (например, отметьте отметки времени создания файла, параметры ввода и т. Д.).
Использование GNU Parallel сделает ваш скрипт еще короче и, возможно, более эффективным:
parallel 'echo "Processing "{}" ..."; do_something_important {}' ::: apache-*.log
Это запустит одно задание на ядро процессора и продолжит это делать до тех пор, пока все файлы не будут обработаны.
Ваше решение будет в основном разделять задания на группы перед запуском. Здесь 32 задания в 4 группах:
[/g1]
GNU Parallel вместо этого запускает новый процесс, когда заканчивается - сохранение активных CPU и, следовательно, экономия времени:
[/g2]
Чтобы узнать больше:
Я должен был сделать это недавно и получил следующее решение:
while true; do
wait -n || {
code="$?"
([[ $code = "127" ]] && exit 0 || exit "$code")
break
}
done;
Вот как это работает:
wait -n
завершается, как только один из ( потенциально много) фоновые задания завершаются. Он всегда оценивает значение true, и цикл продолжается до:
127
: последнее фоновое задание успешно завершено. В этом случае мы игнорируем код выхода и выходим из под-оболочки с кодом 0. С помощью set -e
это гарантирует, что сценарий закончится раньше и пройдет через код выхода любого неудачного фонового задания.
wait $(jobs -p)
для ожидания новых созданных заданий. – lambacck 27 April 2016 в 14:31wait
без эквивалента аргументов? – Olivier Lalonde 4 May 2017 в 06:25wait $(jobs -rp)
, если у вас есть другие заданные задания (например, когда вы приостановили vim с помощью Ctrl + Z): дополнительный флаг-r
отфильтровывает задания running i>. – Luc 5 May 2018 в 22:33