Задать вопрос

Запуск только одной копии скрипта на Python?

Есть скрипт на питоне, запускается по крону, выполняться может долго, запуск двух копий нежелателен.


Есть готовые решения, как запускать скрипт только если предыдущий уже отработал?


Платформа Windows, но хотелось бы кроссплатформенно.
  • Вопрос задан
  • 6639 просмотров
Подписаться 5 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 8
@IlVin
Как я не допускаю второй копии скрипта.

При старте:
1) Создаю lock файл
2) Делаю flock на lock файл (Режим LOCK_NB). Если не получилось, то завершение работы.
3) Записываю в него pid
4) Запоминаю inode файла

При работе скрипта делаю периодическую проверку:
1) Проверяю существование файла. Если файла нет — завершение работы.
2) Проверяю inode файла. Если не совпадает — завершение работы
3) Считываю pid. Если не совпадает с реальным — завершение работы

При завершении работы скрипта:
1) Закрываю lock файл.
Ответ написан
Комментировать
@glebkk
Делал у себя вот так.

  pidfile = "/tmp/server.pid"

  def check_pid(pid):
    """ Check For the existence of a unix pid. """
    try:
      os.kill(pid, 0)
    except OSError:
      return False
    else:
      return True

  if os.path.isfile(pidfile):
    pid = long(open(pidfile, 'r').read())
    if check_pid(pid):
      print "%s already exists, exiting" % pidfile
      sys.exit()

  pid = str(os.getpid())
  file(pidfile, 'w').write(pid)

  # actual code

  # finish
  os.unlink(pidfile)


* This source code was highlighted with Source Code Highlighter.
Ответ написан
Комментировать
Lerg
@Lerg
Defold, Corona, Lua, GameDev
Ещё способ это проверять на занятость сетевой порт, на котором слушает скрипт. Если занять порт не удалось, значит скрипт уже запущен — выход.
Ответ написан
el777
@el777
Я тоже раньше все делал через ручные lock-файлы. Но в этом гемора больше, чем пользы.
В линуксе есть хорошая утилитка lckdo — теперь все кроновые задачи запускаю через нее.
Возможно она есть и для винды.
Ответ написан
Комментировать
@phikus
*/5 * * * * pgrep -f script_name &>/dev/null || script_name
Ответ написан
Комментировать
sevka_fedoroff
@sevka_fedoroff
Я в Линукс для этого получаю список процессов при старте скрипта, выполняя команду «ps» операционной системы, и проверяю, не висит ли там уже такой процесс. Не знаю, можно ли в Виндоуз получить список процессов.
Ответ написан
frol
@frol
Линуксоид
Готовое решение: lockfile.
Ответ написан
Комментировать
olegchir
@olegchir
performance engineer
Тема локфайлов уже раскрыта, но это не единственный способ проверить, что скрипт уже запущен.

Например, можно проверять с помощью обертки, умеющей отвечать на запросы по сети. Когда такая обертка стартует второй раз, она рассылает броадкаст (каким образом — зависит от уровня извращенности автора), и слушает ответы.

У лок-файлов есть минус: если скрипт вылетит с ошибкой до того как завершится, то некому будет удалять лок-файл, система вечно будет считать что скрипт работает. С другой стороны, у сетевой обертки такой проблемы нет. Второй плюс — это решение можно в дальнейшем будет расширить на несколько серверов, и менять почти ничего не придется. Основной минус — эту байду придется писать, что займет какое-то время…
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы