Назад | Перейти на главную страницу

Мгновенно cron, гарантируя только один экземпляр

Есть ли способ запускать скрипт каждую минуту (или 2, или 5 и т. Д.), Но только если он еще не запущен?

У нас есть набор скриптов, которые нужно запускать каждую минуту. Иногда они могут начинаться и заканчиваться за секунду, а иногда и продолжаться 5 минут.

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

Мы могли бы написать своего собственного маленького менеджера, но мне интересно, существует ли уже более модное решение.

лучший способ - использовать flock вместо pidfile. проверьте страницу руководства: стадо (1). Преимущество состоит в том, что независимо от того, как процесс завершается / умирает, блокировка исчезает вместе с ним.

Я был бы склонен согласиться с ответом файла pid от Warner. Однако выполняет ли это следующая функция Anacron?

-s
    Serialize execution of jobs. Anacron will not start a new job before the previous one finished. 

Я сам не тестировал, я не нахожу достаточно подробную документацию по anacron ...

Если вы хотите быть особенно ленивым ;-) Вы можете просто выполнить выход из сценария, если greping через вывод ps возвращает процесс как запущенный. Но лучше всего использовать файл lock / pid.

Это подходящее решение для такого подхода. Обычно используется файл pid, и для процесса выполняется тест pid, чтобы убедиться, что он работает. Если он устарел, файл блокировки будет удален, и процесс все равно будет запущен.

Любой дополнительный интеллект обычно записывается в самом программном обеспечении в виде демона, а не в cron.

Если ваши скрипты написаны на языке, который поддерживает системный вызов flock (2), то вы также можете flock () заблокировать файл с вызовом функции. Пример:

Если вы застряли в Bash или другом языке сценариев, который не поддерживает это, уже предложенное решение с стадо (1) тоже хорошо.

P.S. В любом случае вам следует создать отдельный файл блокировки только один раз (если он еще не существует) и никогда не удалять его. Каталог "/ var / lock" - хорошее место для таких файлов.

Это решение, если ваш скрипт работает на python (или вы можете создать команду python для запуска перед следующей командой) - на прошлой неделе я столкнулся с этой конкретной проблемой, и, хотя я нашел несколько хороших решений, я решил сделать очень простой и чистый пакет python и загрузил его в PyPI. Вы, конечно, можете заблокировать __file__ чтобы не думать о присвоении ему настраиваемого имени ресурса для блокировки.

Установить с помощью: pip install quicklock

Использовать его предельно просто:

[nate@Nates-MacBook-Pro-3 ~/live] python
Python 2.7.6 (default, Sep  9 2014, 15:04:36)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.39)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from quicklock import singleton
>>> # Let's create a lock so that only one instance of a script will run
...
>>> singleton('hello world')
>>>
>>> # Let's try to do that again, this should fail
...
>>> singleton('hello world')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/nate/live/gallery/env/lib/python2.7/site-packages/quicklock/quicklock.py", line 47, in singleton
    raise RuntimeError('Resource <{}> is currently locked by <Process {}: "{}">'.format(resource, other_process.pid, other_process.name()))
RuntimeError: Resource <hello world> is currently locked by <Process 24801: "python">
>>>
>>> # But if we quit this process, we release the lock automatically
...
>>> ^D
[nate@Nates-MacBook-Pro-3 ~/live] python
Python 2.7.6 (default, Sep  9 2014, 15:04:36)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.39)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from quicklock import singleton
>>> singleton('hello world')
>>>
>>> # No exception was thrown, we own 'hello world'!

Взглянуть: https://pypi.python.org/pypi/quicklock