многопроцессорность для цикла bash - PullRequest
2 голосов
/ 02 декабря 2019

У меня нетривиальный сценарий Bash, имеющий примерно следующую форму:

# Initialization

<generate_data> | while read line; do

    # Run tests and filters on line

    if [ "$tests_pass" ]; then
        echo "$filtered_line"
    fi

done | sort <sort_option> | <consume_data>

# Finalization

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

Полезной целью было бы распространение этой логики. в нескольких дочерних процессах, каждый из которых запускает отдельные циклы фильтра и каждый из которых, в свою очередь, потребляет блоки строк из генератора и каждый из которых создает выходные блоки, объединенные в операцию сортировки. Функциональность такого рода доступна через такие инструменты, как GNU Parallel, но для их использования требуется запускать внешнюю команду для запуска в конвейере.

Имеется ли какой-либо удобный инструмент или функция, которая делает операции над сценарием распределенными по нескольким процессам, не нарушая общую структуру сценария? Я не знаю о встроенной функции Bash, но она наверняка будет полезна.

1 Ответ

3 голосов
/ 05 декабря 2019

Проблема с вызовом внешней команды заключается в отсутствии управляемости кода в отношении перемещения логики фильтра в какую-либо команду, которая может быть вызвана независимо.

Если это является причинойне использует GNU Parallel, звучит так, как будто вы не знаете, что parallel --embed.

--embed сделано именно потому, что людям нужно иметь GNU Parallel в том же файле, что и остальной код.

[output from parallel --embed]

myfilter() {
    while read line; do
      # Run tests and filters on line
      if [ "$tests_pass" ]; then
        echo "$filtered_line"
      fi
    done
}   
export -f myfilter

<generate_data> | parallel --pipe myfilter | sort <sort_option> | <consume_data>

Полученный скрипт будет работать, даже если GNU Parallel не установлен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...