Последовательные и параллельные циклы/команды Bash

Последовательные и параллельные циклы/команды Bash

Я хочу запустить несколько симуляций с помощью инструмента 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.

Связанный контент