# Распараллеливание скриптов Bash Рассмотрим последовательность действий, не зависящих друг от друга — это итерации циклов, или вызовы функций с параметрами. Когда цикл один, или функция одна — это тривиальная задача для распараллеливания. Рассмотрим усложнённую модель с тремя функциями и тремя параметрами для каждой — будем распараллеливать вызовы этих функций с использованием программы `xargs`. Для решения вопроса об экранировании спецсимволов — сначала все параметры кодируем в HEX коды и после этого составляем с ними строки — вызовы функций с параметрами. Далее обходим массив строк и выполняем функции в параллельном режиме. Внутри каждой из них сначала декодируем параметры обратно и затем работаем с ними. Для наглядности замеряем общее время выполнения функций. ```bash #!/bin/bash #---------------------------------------------------------------------------; # три функции с тремя параметрами #---------------------------------------------------------------------------; # первая функция с тремя параметрами function first_func { p1="$(decode "$1")" p2="$(decode "$2")" p3="$(decode "$3")" echo "1 ${FUNCNAME[*]} [$p1] [$p2] [$p3]" sleep 5 # эмуляция работы 5 секунд } # вторая функция с тремя параметрами function second_func { p1="$(decode "$1")" p2="$(decode "$2")" p3="$(decode "$3")" echo "2 ${FUNCNAME[*]} [$p1] [$p2] [$p3]" sleep 5 # эмуляция работы 5 секунд } # третья функция с тремя параметрами function third_func { p1="$(decode "$1")" p2="$(decode "$2")" p3="$(decode "$3")" echo "3 ${FUNCNAME[*]} [$p1] [$p2] [$p3]" sleep 5 # эмуляция работы 5 секунд } #---------------------------------------------------------------------------; # вспомогательные функции и экспорт для дочерних процессов #---------------------------------------------------------------------------; # кодирование символов в HEX коды [U0000-UFFFF] function encode { echo "$1" | uni2ascii -aE -qps; } # декодирование символов из HEX кодов [U0000-UFFFF] function decode { echo "$1" | ascii2uni -aE -q; } # перечисление используемых функций в дочерних процессах bash export -f decode first_func second_func third_func #---------------------------------------------------------------------------; # подготовка массива строк и вывод строк массива #---------------------------------------------------------------------------; # параметры могут содержать любые печатные символы или быть пустыми param0=" \$param\"" param1= param2='"$2"!="$1"' # кодирование параметров p0="$(encode "$param0")" p1="$(encode "$param1")" p2="$(encode "$param2")" # массив строк — вызовы функций с параметрами array[0]="first_func '$p0' '$p1' '$p2'" array[1]="second_func '$p1' '$p2' '$p0'" array[2]="third_func '$p2' '$p0' '$p1'" # вывод строк массива для наглядности printf '%s\n' "${array[@]}" #---------------------------------------------------------------------------; # параллельное выполнение функций и замер общего времени выполнения #---------------------------------------------------------------------------; # текущее время в миллисекундах time_ms="$(date '+%s%3N')" # вывод строк массива и вызов функции для каждой из них в параллельном режиме printf '%s\0' "${array[@]}" | xargs -L1 -0 -P0 bash -c # время работы в миллисекундах echo "Общее время выполнения: $(($(date '+%s%3N') - time_ms)) мс." ``` ## Вывод Строки массива — вызовы функций с параметрами через пробелы в кавычках ``` first_func 'U0020U0024U0070U0061U0072U0061U006DU0022' '' 'U0022U0024U0032U0022U0021U003DU0022U0024U0031U0022' second_func '' 'U0022U0024U0032U0022U0021U003DU0022U0024U0031U0022' 'U0020U0024U0070U0061U0072U0061U006DU0022' third_func 'U0022U0024U0032U0022U0021U003DU0022U0024U0031U0022' 'U0020U0024U0070U0061U0072U0061U006DU0022' '' ``` Параллельная работа функций, порядок может изменяться ``` 3 third_func ["$2"!="$1"] [ $param"] [] 2 second_func [] ["$2"!="$1"] [ $param"] 1 first_func [ $param"] [] ["$2"!="$1"] ``` Время работы функций в миллисекундах ``` Общее время выполнения: 5023 мс. ``` --- © Головин Г.Г., Код с комментариями, 2024