Я хочу запустить несколько симуляций с помощью инструмента Python, который я сделал. Проблема в том, что мне придется вызывать его несколько раз с разными параметрами/аргументами и всем остальным.
На данный момент я использую несколько for
циклов для этой задачи, например:
for simSeed in 1 2 3 4 5
do
for launchPower in 17.76 20.01 21.510 23.76
do
python sim -a $simSeed -p $launchPower
done
done
Чтобы симуляции выполнялись одновременно, я добавляю a &
в конце строки, где вызываю симулятор.
python sim -a $simSeed -p $launchPower &
Используя этот метод, я могу запустить несколько таких семян. Однако, поскольку память моего компьютера ограничена, я хочу переписать приведенный выше скрипт так, чтобы он запускал внутренний for
цикл параллельно, а внешний for
цикл — последовательно.
Например, для simSeed = 1
я хочу, чтобы 5 различных процессов выполнялись с launchPower
равным 17.76 20.01 21.510 23.76
. Как только эта часть будет завершена, я хочу, чтобы скрипт выполнялся для simSeed = 2
и снова 5 различных параллельных процессов с launchPower
равным 17.76 20.01 21.510 23.76
.
Как мне выполнить эту задачу?
Краткий обзор:
Я хочу, чтобы внешний цикл выполнялся последовательно, а внутренний цикл — параллельно, чтобы после завершения последнего параллельного процесса внутреннего цикла внешний цикл переходил к следующей итерации.
решение1
GNU Parallel имеет несколько опций для ограничения использования ресурсов при параллельном запуске заданий.
Основное использование двух вложенных циклов будет таким:
parallel python sim -a {1} -p {2} ::: 1 2 3 4 5 ::: 17.76 20.01 21.510 23.76
Если вы хотите запустить не более 5 заданий одновременно, например, вы можете сказать
parallel -j5 python <etc.>
В качестве альтернативы вы можете использовать --memfree
опцию запуска новых заданий только при наличии достаточного объема свободной памяти, например, не менее 256 МБ.
parallel --memfree 256M python <etc.>
Обратите внимание, что последний вариант завершит последнее запущенное задание, если объем памяти опустится ниже 50% от указанного «резервного» значения (но оно будет автоматически поставлено в очередь для наверстывания упущенного).
решение2
Как уже упоминалось в комментариях, именно parallel
для этого и нужен GNU:
for simSeed in 1 2 3 4 5
do
## Launch 5 instances in parallel
parallel -j5 python sim -a $simSeed -p {} ::: 17.76 20.01 21.510 23.76
done
решение3
Вы можете сохранить соответствующие идентификаторы процессов и wait
дождаться их завершения:
for simSeed in {1..5}; do
pids=()
for launchPower in 17.76 20.01 21.510 23.76; do
python sim -a $simSeed -p $launchPower &
pids+=($!)
done
wait ${pids[@]}
done
pids
массив идентификаторов процессов фоновых заданий внутреннего цикла. При этом ${pids[@]}
все элементы массива передаются команде wait.