1
0
Fork 0
pomodoro/archive/parallelizing-bash-scripts.md
2024-12-29 10:39:47 +03:00

5.5 KiB
Raw Permalink Blame History

Распараллеливание скриптов Bash

Рассмотрим последовательность действий, не зависящих друг от друга — это итерации циклов, или вызовы функций с параметрами. Когда цикл один, или функция одна — это тривиальная задача для распараллеливания. Рассмотрим усложнённую модель с тремя функциями и тремя параметрами для каждой — будем распараллеливать вызовы этих функций с использованием программы xargs.

Для решения вопроса об экранировании спецсимволов — сначала все параметры кодируем в HEX коды и после этого составляем с ними строки — вызовы функций с параметрами. Далее обходим массив строк и выполняем функции в параллельном режиме. Внутри каждой из них сначала декодируем параметры обратно и затем работаем с ними. Для наглядности замеряем общее время выполнения функций.

#!/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