Python: защита от повторного запуска

Python: защита от повторного запуска

Защиту от запуска нескольких копий программы мне срочно понадобилась когда я решил запилить телеграм-бота. Поскольку бот должен работать 24/7 без перерывов на обед, встал вопрос автозапуска и контроля работы бота. Работать бот должен бесперебойно. Автозапуск не решал задачи ибо автозапуск происходит при старте системы, а дальше может произойти сбой и процесс бота остановится. За этим кто-то должен следить. Вопрос: кто? Ответ: да сам бот пускай и следит. Первый мой способ, описанный ниже, не дал ожидаемого результата.

Логика работы

Логика работы проверки наличия запущенного процесса строится на двух моментах:

  1. Файл с pid’ом
  2. Поиск процесса с pid’ом из файла

То есть, когда запускается процесс впервые, то создается файл с идентификатором процесса. Когда происходит повторный запуск, то программа извлекает идентификатор из файла, проверяет есть ли процесс таким идентификатором и если такой процесс есть, завершает свою работу, если нет, пишет в файл свой pid и продолжает свою работу.

Реализация

import os, psutil, sys

pid_file_path = '/dev/shm/pybot.pid'

if os.path.exists( pid_file_path ):
	pid_file = open( pid_file_path, "r" )
	pid = int( pid_file.read() )
	pid_file.close()
	if psutil.pid_exists( pid ):
		print( 'Бот уже запущен' )
		sys.exit()

pid_file = open( pid_file_path, "w" )
pid_file.write( str( os.getpid() ) )
pid_file.close()

Файл с идентификатором процесса пишется в оперативную память (dev/shm). Во-первых: это быстрее чем писать на диск, во-вторых: при перезагрузке этот файл исчезнет.

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

Через какое-то время я замечал что запущено два и более процесса, что нарушало работу бота. Поскольку этот способ не дал ожидаемого результата. И начал искать. Совсем случайно я наткнулся на готовое решение.

Модуль Tendo

Безотказное решение. Не знаю на чем основана его логика, но работает безотказно и проверено многочасовыми аптаймами. Как в аптеке — процесс всегда один. А добавление в проект — элементарно.

В начало файла надо вставить код из нескольких строк:

from tendo import singleton


try:
	me = singleton.SingleInstance()
except:
	sys.exit()

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

На сайте отсутствует реклама

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

Номер карты

Заранее спасибо!

Бидюков Денис

Эксперт по сайтам

Занимаюсь продвижением личного бренда с помощью сайта и SEO. Если Вы хотите из обычного сантехника, электрика, врача или фотографа стать востребованным и высокооплачиваемым  специалистом, то я с легкостью Вам помогу.

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *