использование параллельного для обработки уникальных входных файлов к уникальным выходным файлам

На другом компьютере с загрузкой высокоскоростного соединения и использованием unetbootin. Unetbootin поможет Вам загрузить salix, щенка или zenwalk Linux. Используйте unetbootin для перемещения его в карту памяти. если можно заставить ноутбук загружаться с картой памяти затем, можно установить любое из этого. Все три будут работать над спецификациями, которые Вы упомянули.

18
13.09.2017, 02:51
6 ответов

Параллель GNU разработана для этого вида задач:

parallel customScript -c 33 -I -file {} -a -v 55 '>' {.}.output ::: *.input

или:

ls | parallel customScript -c 33 -I -file {} -a -v 55 '>' {.}.output

Это выполнит задания на ядро процессора.

Можно установить Параллель GNU просто:

wget https://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel
chmod 755 parallel
cp parallel sem

Посмотрите вводные видео для Параллели GNU для узнавания больше: https://www.youtube.com/playlist? list=PL284C9FF2488BC6D1

27
27.01.2020, 19:45
  • 1
    Большой ответ (и важные пункты для чтения моего запроса использования параллели). –  J Jones 28.02.2012, 05:17

Стандартный способ сделать это должно установить очередь и породить любое число рабочих, которые знают, как вытянуть что-то от очереди и обработать ее. Можно использовать FIFO (иначе именованный канал) для коммуникации между этими процессами.

Ниже наивный пример для демонстрации понятия.

Простой сценарий очереди:

#!/bin/sh
mkfifo /tmp/location-queue
for i in inputfiles/*; do
  echo $i > /tmp/location-queue
done
rm /tmp/location-queue

И рабочий:

#!/bin/sh
while read file < /tmp/location-queue; do
  process_file "$file"
done

process_file мог быть определен где-нибудь в Вашем рабочем, и это может сделать то, что Вам нужен он, чтобы сделать.

После того как у Вас есть те две части, у Вас может быть простой монитор, который запускает процесс очереди и любое количество рабочих процессов.

Сценарий монитора:

#!/bin/sh
queue.sh &
num_workers="$1"
i=0
while [ $i < $num_workers ]; do
  worker.sh &
  echo $! >> /tmp/worker.pids
  i=$((i+1))
done
monitor_workers

Там у Вас есть он. Если Вы на самом деле делаете это, лучше установить FIFO в мониторе и передать путь и к очереди и к рабочим, таким образом, они не связываются и не придерживаются определенное местоположение для FIFO. Я установил его этот путь в ответе конкретно, таким образом, ясно, что, что Вы используете, поскольку Вы читаете его.

5
27.01.2020, 19:45
  • 1
    Как монитор достаточно умен к паузе, мечущей икру на новых рабочих, пока следующее не закончилось (иначе, где $i когда-либо становится постепенно уменьшенным)?----Отвечая на мое собственное редактирование, рабочие никогда не уходят, они просто обрабатывают файлы, пока вся обработка не была исчерпана (следовательно цикл с условием продолжения в 'процессорах' также). –  J Jones 20.02.2012, 15:46
  • 2
    Какова "monitor_workers" строка в конце выполнения сценария монитора? –  J Jones 20.02.2012, 15:51
  • 3
    @JJones - monitor_workers точно так же, как process_file - это - функция, которая делает то, что Вы хотите. О мониторе - Вы были правы; это должно сохранить pids своих рабочих (таким образом, это может отправить сигнал уничтожения), и счетчик должен быть увеличен, когда это запускает рабочего. Я отредактировал ответ для включения этого. –  Shawn J. Goff 20.02.2012, 16:12
  • 4
    я действительно ценю Вашу работу, но я думаю, что необходимо использовать GNU parallel. Я думаю, что это - Ваша идея, полностью реализованная. –  motobói 24.09.2015, 04:28

Обычно доступный инструмент, который может сделать распараллеливание, делают. GNU делает, и у немногих других есть a -j опция выполнить параллельные сборки.

.SUFFIXES: .input .output
.input.output:
        process_one_file <$< >$@.tmp
        mv -f $@.tmp $@

Выполненный make как это (я принимаю, Ваши имена файлов не содержат специальных символов, make бесполезно с теми):

make -j 4 $(for x in *.input; do echo ${x%.*}.output; done)
4
27.01.2020, 19:45
  • 1
    , по моему скромному мнению, это - самое умное решение :) –  h4unt3r 04.06.2014, 21:14

Это должно выполнить ту же команду на большом наборе файлов в текущем каталоге:

#!/bin/sh
trap 'worker=`expr $worker - 1`' USR1  # free up a worker
worker=0  # current worker
num_workers=10  # maximum number of workers
for file in *.txt; do
    if [ $worker -lt $num_workers ]; then
        {   customScript -c 33 -I -file $file -a -v 55 > `basename $file .txt`.outtxt 
            kill -USR1 $$ 2>/dev/null  # signal parent that we're free
        } &
        echo $worker/$num_worker $! $file  # feedback to caller
        worker=`expr $worker + 1`
    else
        wait # for a worker to finish
    fi
done

Это работает customScript на каждом txt файл, вставляя вывод outtxt файлы. Изменение, как Вам нужно. Ключ к тому, чтобы заставлять это работать является обработкой сигналов, с помощью SIGUSR1, таким образом, дочерний процесс может позволить родительскому процессу знать, что это сделано. Используя SIGCHLD не будет работать, так как большинство операторов в сценарии сгенерирует сигналы SIGCHLD к сценарию оболочки. Я попробовал эту замену Вашей команды sleep 1, программа использовала 0,28 с пользовательского CPU и 0,14 с системного CPU; это было только приблизительно на 400 файлах.

3
27.01.2020, 19:45
  • 1
    Как 'ожидание' достаточно умно для взятия того же файла, который в настоящее время выполняется с помощью итераций, и повторно введите одноуровневый элемент "если" оператор? –  J Jones 21.02.2012, 15:09
  • 2
    Это не wait это достаточно 'умно'; но это возвратится после получения SIGUSR1 сигнал. Ребенок/рабочий отправляет a SIGUSR1 к родителю, который пойман (trap), и декременты $worker (trap пункт), и возвращаются неправильно из wait, разрешение if [ $worker -lt $num_workers ] пункт для выполнения. –  Arcege 21.02.2012, 15:58

Другой пример:

ls *.txt | parallel 'sort {} > {.}.sorted.txt'

Я нашел другие примеры излишне сложными, когда в большинстве случаев вышеприведенный пример - это то, что вы, возможно, искали.

5
27.01.2020, 19:45

Или просто используйте xargs -P,нет необходимости устанавливать дополнительное ПО:

find. -type f -print0 | xargs -0 -I'XXX' -P4 -n1 custom_script -input "XXX" -output "XXX.out"

Немного пояснений к опциям:

  • -I'XXX'задает строку, которая будет заменена в шаблоне команды именем файла
  • -P4будет запускать 4 процесса параллельно
  • -n1будет помещать только один файл на выполнение, даже если найдено два XXX
  • -print0и -0работают вместе, позволяя использовать специальные символы. (как пробелы )в именах файлов
0
27.01.2020, 19:45

Теги

Похожие вопросы