Вопрос: Ограничение количества одновременных экземпляров программы, выполняемой в скрипте Perl (до> 1)


Я использую ресурсоемкую программу в Perl-скрипте [специально rclone для передачи файлов на Google Диск].

Мне еще предстоит выяснить, как я хочу позвонить rclone, так как мне нужно ограничить количество экземпляров rclone на основе некоторого условия ( что-нибудь  для предотвращения перегрузки сервера, замораживания, сбоев и т. д.). Я бы хотел, чтобы сценарий дождался «условий» apt-системы (это может быть какое-то длительное или неопределенное количество времени), прежде чем он выполнит rclone,

Некоторые детали:

  • Сам скрипт по существу передал путь к файлу или каталогу, содержащий (возможно, многочисленные) файлы другой программой (эта программа, написанная на Python - вызов этой программы <A> для справки).
  • <A> возвращает значение только скрипту и, следовательно, ничего не знает о скрипте или rclone, кроме того, что он принимает ввод.
  • <A> не могут быть изменены (т. е. <A> находится за пределами моего ken)
  • <A> огонь с различными интервалами [т. иногда он будет выполнять сценарий много раз подряд подряд (создание нескольких экземпляров), в других случаях он может срабатывать только раз в несколько часов, минут и т. д.]
  • Предположим, что rclone не могут быть изменены напрямую (т.е. снова за пределами моего ken).
  • Если это абсолютно необходимо, количество экземпляров сценария может быть ограничено вместо rclone (хотя я бы предпочел, чтобы это было rclone, так как обработка, выполняемая скриптом, довольно легкая и не требует ограничений).
  • Модули подходят для использования.
  • Я бы хотел избежать использования Unix-подобных команд операционной системы, таких как pgrep а также ps (если это абсолютно необходимо).

В настоящее время я использую довольно плохо написанный сценарий bash вместо скрипта Perl. Сценарий bash реализует рудиментарный (плохо спроектированный) «цикл проверки / сна», используя pgrep -wc, sleep, while петли и if заявления. (Честно говоря, я даже не думаю, что скрипт bash действительно работает / помогает atm.)


3


источник


Ответы:


На мгновение я предполагаю, что ваш сценарий - единственное, что работает rclone, Если вы хотите выполнить только одну копию, вы просто используете файл блокировки ,

Для N экземпляров (для небольшого N) у меня просто есть N lockfiles - попробуйте выполнить каждую попытку по очереди, в цикле; приостановить, если все блокировки уже сохранены, и повторите попытку позже, в цикле. После того, как он заблокирован, запустите rclone затем отпустите замок, когда это будет сделано.


Более здравый подход состоял бы в использовании семафоров SysV, но, если вы не хотите большого N, действительно заботитесь о времени ответа или беспокоитесь о справедливости между абонентами, вряд ли стоит потратить время на их изучение.


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


4



GNU Parallel может работать в очереди заданий https://www.gnu.org/software/parallel/man.html#EXAMPLE:-GNU-Parallel-as-queue-system-batch-manager

true >jobqueue; tail -n+0 -f jobqueue | parallel -j10 --timeout 1h rclone

А затем запустите <A> как это:

<A> >> jobqueue

Вы будете время от времени убирать jobqueue, Но если <A> производит безумный объем данных, тогда обычно будет достаточно просто его обнулить ( true >jobqueue) при каждой перезагрузке.


2