У меня есть сценарий bash, который выполняет команду над большим количеством файлов в папке. Как я могу включить в этот сценарий эффект многопоточности, чтобы сценарий выполнялся быстрее?
Я бы использовал что-то вроде parallel
из пакета moreutils
. Ожидается одна команда и список аргументов. По умолчанию он будет вводить один аргумент для каждого экземпляра команды и раскручивать столько параллельных экземпляров, сколько у вас процессорных ядер.
Важно то, что у вас есть рабочая нагрузка, которую можно пакетировать. Хороший пример - наличие кучи файлов для выполнения отдельных операций. Но делать вещи с синхронным выводом (например, добавлять несколько файлов в один zip-архив) сложнее.
Хорошим примером, адаптированным со страницы man parallel
, является обработка неизвестного количества файлов через UFRAW, по одному на процессор.
parallel ufraw -o processed -- *.NEF
С Параллелью GNU можно сделать это:
parallel ./myscript.sh --option1 --inputfile {} --outputfile {}.out ::: files*
Это примет значение по умолчанию для выполнения одного задания на поток ЦП параллельно.
Видеть, что будет выполнено использование --dry-run
:
parallel --dry-run ./myscript.sh --option1 --inputfile {} --outputfile {}.out ::: files*
Параллель GNU является общим parallelizer и делает, легко выполнить задания параллельно на той же машине или на нескольких машинах, к которым у Вас есть ssh доступ.
Если у Вас есть 32 различных задания, Вы хотите работать на 4 центральных процессорах, прямой способ параллелизировать состоит в том, чтобы выполнить 8 заданий на каждом ЦП:
Параллель GNU вместо этого порождает новый процесс, когда каждый заканчивает - хранение активных центральных процессоров и таким образом экономящее время:
Установка
Из соображений безопасности необходимо установить Параллель GNU с диспетчером пакетов, но если Параллель GNU не упаковывается для распределения, можно сделать персональную установку, которая не требует корневого доступа. Это может быть сделано через 10 секунд путем выполнения этого:
$ (wget -O - pi.dk/3 || lynx -source pi.dk/3 || curl pi.dk/3/ || \
fetch -o - http://pi.dk/3 ) > install.sh
$ sha1sum install.sh | grep 3374ec53bacb199b245af2dda86df6c9
12345678 3374ec53 bacb199b 245af2dd a86df6c9
$ md5sum install.sh | grep 029a9ac06e8b5bc6052eac57b2c3c9ca
029a9ac0 6e8b5bc6 052eac57 b2c3c9ca
$ sha512sum install.sh | grep f517006d9897747bed8a4694b1acba1b
40f53af6 9e20dae5 713ba06c f517006d 9897747b ed8a4694 b1acba1b 1464beb4
60055629 3f2356f3 3e9c4e3c 76e3f3af a9db4b32 bd33322b 975696fc e6b23cfb
$ bash install.sh
Поскольку другие опции инсталляции видят http://git.savannah.gnu.org/cgit/parallel.git/tree/README
Подробнее
Посмотрите больше примеров: https://www.gnu.org/software/parallel/man.html#EXAMPLE:-Working-as-xargs - n1.-Argument-appending
Посмотрите вводные видео: https://www.youtube.com/playlist? list=PL284C9FF2488BC6D1
Обход через учебное руководство: http://www.gnu.org/software/parallel/parallel_tutorial.html
Прочитайте книгу (по крайней мере, глава 2): https://doi.org/10.5281/zenodo.1146014
Зарегистрируйтесь в почтовой рассылке для получения поддержки: https://lists.gnu.org/mailman/listinfo/parallel