Можно ли выполнить функцию в фоновом режиме из функции, которая уже работает в фоновом режиме?

Вопрос или проблема

Учитывая следующий скрипт:

if [[ -z "$DOWNLOAD_ONLY" || "$DOWNLOAD_ONLY" = *conditions* ]]; then
  function get_condition {
    curl -s "https://conditions.com" | jq '.included[].attributes | select(retracted)' | jq --arg item $2 '. + {item: $item}' > "$1_$2.json"
  }

  function conditions {
    for item in `cat items.json | jq -r '.data[].id'`
    do
      get_condition $1 $item
    done

    jq -s '.' $1_*.json | jq 'reduce .[] as $item (retracted)' > "$1.json"

    rm $1_*.json
  }

  curl "https://items.com" | jq '.' > "items.json"

  for language in cs da de en es fr it nl pl pt sv zh
  do
    conditions $language &
  done

  wait
fi

Могу ли я добавить & к get_condition $1 $item, а затем вызвать wait позже?

Я предполагаю, что проблема может заключаться в том, что ожидание в b будет ждать все процессы, запущенные из сценария оболочки, что приведет к взаимной блокировке. Это не проблема, wait ожидает детей текущей (под)оболочки; запуск b в фоновом режиме заставляет его иметь свою собственную под-оболочку с собственным списком задач и дочерних процессов.

Так что

  function b {
    for n in `cat ok.txt`
    do
      a $1 $n &
    done
    wait
  }

будет работать хорошо с этой точки зрения — b будет ждать a, которые он запустил, и только их.

.

Ответ или решение

Конечно, можно выполнить функцию в фоновом режиме из функции, которая уже выполняется в фоновом режиме. Ваша основная забота заключается в том, как управлять этими процессами, чтобы избежать возможных проблем, таких как блокировки.

Основные моменты:

  1. Фоновое выполнение функций:

    • Использование символа & для выполнения функций в фоновом режиме позволяет запускать несколько процессов одновременно, что является полезным для задач, требующих сетевых запросов или длительных операций ввода-вывода.
  2. Использование wait:

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

Ваш сценарий:

В приведённом вами коде, функция conditions вызывает функцию get_condition, и если добавить символ & после вызова get_condition, вы запустите этот процесс в фоновом режиме. Пример:

get_condition $1 $item &

Это позволит вашей функции conditions продолжать выполнение и запускать несколько экземпляров get_condition параллельно для различных элементов item.

Последующий вызов wait:

Каждая выполнение get_condition будет происходить в своем дочернем процессе, и вызов wait в функции conditions будет ожидать завершения всех фоновых процессов, которые были инициированы этой функцией.

Таким образом, ваш код может выглядеть следующим образом:

function conditions {
    for item in `cat items.json | jq -r '.data[].id'`
    do
        get_condition $1 $item &
    done

    wait

    jq -s '.' $1_*.json | jq 'reduce .[] as $item (retracted)' > "$1.json"

    rm $1_*.json
}

Что учесть:

  • Конкуренция за ресурсы: Если функции get_condition делают множество сетевых запросов одновременно, это может привести к превышению лимитов API или к сильной нагрузке на сеть. Применение задержек (например, sleep) между запусками может помочь смягчить эту проблему.

  • Ошибки и обработка исключений: Учтите, что даже в фоновом режиме ошибки могут произойти в запущенных функциях. Убедитесь, что вы обрабатываете возможные ошибки или добавляете механизмы повторного запуска по мере необходимости.

Заключение:

С добавлением & к вызову get_condition и использованием wait для ожидания этих фоновый процессов, вы сможете добиться требуемого поведения без угрозы блокировок. Это подход, который позволяет эффективно управлять многопоточными операциями в Bash-скрипте, повышая производительность и отзывчивость вашего приложения.

Оцените материал
Добавить комментарий

Капча загружается...