6

Если я хочу обработать большое количество файлов с помощью команды "do_something", которая может использовать только одно ядро, каков наилучший способ использования всех доступных ядер, если предположить, что каждый файл может обрабатываться независимо?

В этот момент я делаю что-то вроде этого:

#!/bin/zsh
TASK_LIMIT=8
TASKS=0
for i in *(.)
{
  do_something "$i"&
  TASKS=$(($TASKS+1))
  if [[ $TASKS -ge $TASK_LIMIT ]]; then
    wait; TASKS=0; fi
}
wait

Очевидно, что это неэффективно, потому что после достижения $ TASK_LIMIT он ждет, когда все "do_something" заканчивают. Например, в моем реальном скрипте я использую около 500% моего 8-ядерного процессора вместо> 700%.

Запуск без $ TASK_LIMIT не вариант, потому что do_something может потреблять много памяти.

В идеале сценарий должен пытаться сохранить количество параллельных задач в $ TASK_LIMIT: например, если задача 1 из 8 завершена и требуется обработать хотя бы еще один файл, сценарий должен выполнить следующую операцию "do_something" вместо ожидания оставшихся 7 задач заканчивать. Есть ли способ добиться этого в Zsh или Bash?

2 ответа2

6

Я настоятельно рекомендую взглянуть на GNU параллельно. Он делает именно то, что вы хотите, и не зависит от какой-либо конкретной оболочки.

0

Помните, сколько процессов вы начали. Когда процесс закончится, уменьшите количество. Когда количество будет меньше максимального, начните новый процесс.

Единственная проблема заключается в том, как сигнализировать об окончании процесса. Например, вы можете создать файл / файл с заданным именем в / tmp (состоит из $$ и $ BASHPID).

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .