98 lines
5.5 KiB
HTML
98 lines
5.5 KiB
HTML
# Распараллеливание скриптов 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
|