Запуск сценария оболочки параллельно - PullRequest
41 голосов
/ 05 апреля 2011

У меня есть сценарий оболочки, который

  1. перемешивает большой текстовый файл (6 миллионов строк и 6 столбцов)
  2. сортирует файл по первому столбцу
  3. выводит 1000 файлов

Таким образом, псевдокод выглядит следующим образом

file1.sh 

#!/bin/bash
for i in $(seq 1 1000)
do

  Generating random numbers here , sorting  and outputting to file$i.txt  

done

Есть ли способ запустить этот сценарий оболочки в parallel, чтобы в полной мере использовать многоядерные процессоры?

В данный момент. /file1.sh выполняется в последовательности от 1 до 1000 запусков, и это очень медленно.

Спасибо за вашу помощь.

Ответы [ 7 ]

85 голосов
/ 05 апреля 2011

Еще один очень удобный способ сделать это - gnu параллельно , который стоит установить, если у вас его еще нет; это неоценимо, если задачи не обязательно занимают одинаковое количество времени.

seq 1000 | parallel -j 8 --workdir $PWD ./myrun {}

запустит ./myrun 1, ./myrun 2 и т. Д., Убедившись, что одновременно выполняется 8 заданий. Он также может принимать списки узлов, если вы хотите работать на нескольких узлах одновременно, например, в задании PBS; наши инструкции для наших пользователей о том, как это сделать в нашей системе, здесь .

Обновлено с добавлением: Вы хотите убедиться, что вы используете gnu-parallel, а не более ограниченную утилиту с тем же именем, которая входит в пакет moreutils (описана расхождение истории двух здесь .)

42 голосов
/ 05 апреля 2011

Извлечение bash subshells , они могут использоваться для параллельного запуска частей скрипта.

Я не проверял это, но это может быть началом:

#!/bin/bash
for i in $(seq 1 1000)
do
   ( Generating random numbers here , sorting  and outputting to file$i.txt ) &
   if (( $i % 10 == 0 )); then wait; fi # Limit to 10 concurrent subshells.
done
wait
13 голосов
/ 05 апреля 2011

Чтобы заставить вещи работать параллельно, вы используете '&' в конце команды оболочки для запуска в фоновом режиме, тогда wait будет по умолчанию (т.е. без аргументов) ждать, пока все фоновые процессы завершатся. Так что, возможно, начните 10 параллельно, затем подождите, затем сделайте еще десять. Это можно легко сделать с помощью двух вложенных циклов.

9 голосов
/ 21 сентября 2011

Существует целый список программ , которые могут запускать задания параллельно из оболочки, которая даже включает сравнения между ними, в документации по параллельному GNU. Существует множество решений. Еще одна хорошая новость заключается в том, что они, вероятно, весьма эффективны в планировании заданий, поэтому все ядра / процессоры постоянно заняты.

4 голосов
/ 21 сентября 2011

Существует простая, переносимая программа, которая сделает это за вас: PPSS . PPSS автоматически планирует для вас задания, проверяя, сколько ядер доступно, и запускает другое задание каждый раз, когда другое только что завершилось.

0 голосов
/ 21 марта 2018
IDLE_CPU=1
NCPU=$(nproc)

int_childs() {
    trap - INT
    while IFS=$'\n' read -r pid; do
        kill -s SIGINT -$pid
    done < <(jobs -p -r)
    kill -s SIGINT -$$
}

# cmds is array that hold commands
# the complex thing is display which will handle all cmd output
# and serialized it correctly

trap int_childs INT
{
    exec 2>&1
    set -m

    if [ $NCPU -gt $IDLE_CPU ]; then
        for cmd in "${cmds[@]}"; do
            $cmd &
            while [ $(jobs -pr |wc -l) -ge $((NCPU - IDLE_CPU)) ]; do
                wait -n
            done
        done
        wait

    else
        for cmd in "${cmds[@]}"; do
            $cmd
        done
    fi
} | display
0 голосов
/ 04 июля 2012

генерировать случайные числа легко.Предположим, у вас есть огромный файл, такой как база данных магазина, и вы хотите переписать этот файл на определенной основе.Моя идея состояла в том, чтобы рассчитать количество ядер, разделить файл на количество ядер, создать файл script.cfg, split.sh и Recombine.sh split.sh разделит файл на количество ядер, клон script.cfg (скрипт, который меняет материалв этих огромных файлах), клонируйте script.cgf во сколько ядер, сделайте их исполняемыми, найдите и замените в клонах некоторые переменные, которые должны знать, какую часть файла обрабатывать, и запустите их в фоновом режиме, когда клон завершен, генерируют клонФайл $ core.ok, поэтому, когда все клоны будут готовы, цикл скажет объединить частичные результаты в один только тогда, когда будут сгенерированы все файлы .ok.это можно сделать с помощью «wait», но мне кажется, что мой путь

http://www.linux -romania.com / product.php? id_product = 76 взгляд внизу частично переведен на ENтаким образом я могу обработать 20000 статей с 16 столбцами за 2 минуты (четырехъядерный процессор) вместо 8 (одноядерный). Вам нужно заботиться о температуре процессора, потому что все ядра работают на 100%

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...