2016-11-16 1 views
1

Я новичок в GNU Parallel, и я буду рад, если вы укажете некоторые ошибки и недоразумения. Я прочитал руководство, но он говорит в основном об одноэтапной операции, в которой необходимо указать определение «действие» в синтаксисе GNU Parallel (распаковка, перемещение и т. Д.), И ничего не указано о многоэтапных шагах, когда вы необходимо выполнить несколько действий без изменения (значительно) кода (если курс вообще возможен)Поддельное распараллеливание в скрипте над циклом (строка foreach) без существенных изменений кода

Возможно ли «поддельная» параллельная обработка в коде, который его не поддерживает? Код имеет цикл (есть список файлов в любом формате, и в какой-то момент он подходит к циклу), и все, что вам нужно, чтобы этот код выполнял определенные действия (независимо от того, какие действия) для всех файлов одновременно, а не последовательно (без изменения кода по существу или только около 138 строк - см. ниже). Для такого рода параллельной обработки не требуется разделять файлы или что-то в этом роде, а просто обрабатывать сразу все файлы.

В качестве примера: здесь является частью кода, который интересует, полный код здесь - 138 линия GMT

# <code> actions (see full code - link below) and check input file availability 
#loop 
# 
    foreach line (`awk '{print $0}' $1`) 
# <code> actions (see full code - link below) 
end if 

Источник, полный код: GMT

Может быть, это может быть реализовано с использованием других инструментов, кроме GNU Parallel? Любая помощь полезна. Желательно, например, если таковые имеются. И если вы сделаете весь код параллельным, это, вероятно, вызовет проблемы. Это необходимо в момент цикла.

Thanks

+1

Есть ли причина использовать 'csh', а не' bash'? Кажется, вы тратите весь свой скрипт на множество вызовов 'awk', которые были бы совершенно ненужными в' bash'. Вы также можете поместить весь свой код в 'function', если вы используете' bash', затем «экспортируете» функцию в ** GNU Parallel ** и запускаете функцию параллельно с 'parallel someFunc'. –

+0

Также старайтесь избегать таких вещей, как 'grep XYZ someFile | awk 'print $ 3'', а вместо этого 'awk' тоже выполняет поиск' awk'/XYZ/{print $ 3} 'someFile' –

+0

Будет очень сложно переписать все в 'bash'. И код не мой. Тем более, что я все еще просто учился. Много ловушек и так далее. Но я спрашиваю разработчиков (т.е. могу ли я переписать на bash). Благодарю вас за идею. – user2899758

ответ

1

csh имеет множество ограничений; недостаток функций - один из них, и любой скрипт, который длиннее нескольких строк, быстро превратится в беспорядок спагетти. Это важная причина, по которой сценарий в csh обычно не рекомендуется.

Это, как говорится, самый простой способ изменить это - извлечь тело цикла в отдельный скрипт и вызвать это с добавлением &. Например:

main.csh:

#!/bin/csh 

foreach line (`awk '{print $0}' $1`) 
    ./loop.csh "$line" & 
end 

loop.csh:

#!/bin/csh 

set line = "$1" 
echo "=> $line" 
sleep 5 

Вам может понадобиться, чтобы добавить больше параметров, чем просто $line; Я не проверял весь сценарий.

& сделает оболочку продолжением, не дожидаясь завершения команды. Так что, если есть 5000 строк, вы будете запускать 5000 процессов одновременно.Для того, чтобы осуществлять некоторый контроль над количеством одновременных процессов можно использовать параллельный инструмент вместо цикла:

#!/bin/csh 

awk '{print $0}' $1 | parallel ./loop.csh` 

Или, если вы хотите придерживаться петель вы можете использовать pgrep ограничить максимальное количество одновременных процессов:

foreach line (a b c d e f g h i) 
    set numprocs = `pgrep -c loop.csh` 
    if ($numprocs > 2) then 
     sleep 2 
     continue 
    endif 

    ./loop.csh "$line" & 
end 
+0

Большое спасибо! Я попробую. – user2899758

1

Если это приемлемо, чтобы переместить внутреннюю часть петли в сценарий:

parallel inner.csh ::: a b c d e f g h i 

Если inner.csh использует variabl эс, а затем setenv их перед запуском parallel:

setenv myvar myval 
parallel inner.csh ::: a b c 

a, b, and c будет передан в качестве первого арг к inner.csh. Чтобы прочитать аргументы из использования файла:

cat file | parallel inner.csh 

Это также работает для чтения выхода из awk:

awk ... | parallel ... 

Рассмотрим ходьбы через учебник. Ваша командная строка понравится вам: https://www.gnu.org/software/parallel/parallel_tutorial.html

+0

Не могли бы вы рассказать мне, что делать с переменными? Я понимаю, что если они установлены перед циклом, а затем используются в цикле, GNU Parallel запускает новые процессы, которые не связаны с ними. И код не будет работать. Любые советы полезны. Спасибо за помощь. Вместо 'a b c f e f', я должен использовать имена файлов? – user2899758

+0

@ user2899758 См. Edit. –

Смежные вопросы