fbpx

Не запускать второй экземпляр скрипта

478 просмотра
0
0 Комментариев

Приветствую!

Допустим, существует некий скрипт

from time import sleep
 
while True:
    print("hello!")
    sleep(100)

который запускается по cron каждую минуту в centos6. Подскажите пожалуйста, как предотвратить запуск ещё одного экземпляра скрипта, если первый ещё не завершил работу?

Пока нашёл только вот такую штуку

from pid import PidFile
 
with PidFile():
  do_something()

Но увы, её нет в стандартных репах centos6. Я буду очень благодарен за решение, которое работает «из коробки». Заранее спасибо!


Добавить комментарий

2 Answers

Python Опубликовано 19.01.2019
0

С помощью модуля sys мы можем получить название текущего файла. А используя модуль subprocess можем посмотреть количество процессов с таким именем.

import subprocess
import sys
 
# имя текущего процесса
name = sys.argv[0].split('/')[-1]
# команда для поиска процессов с таким именем
com = 'pgrep -f ' + name
 
# запускаем команду
p = subprocess.Popen([com], stdout=subprocess.PIPE, shell=True)
# берём результат
res = p.communicate()[0]
# в Питоне 3.* результат – байты, его нужно привести к строке
if isinstance(res, bytes):
    res = res.decode("utf-8")
# достаём из текста список процессов
res = [str(x) for x in res.split('\n') if len(x) > 0]
 
# расходимся, если процесс уже запущен
if len(res) > 0:
    print('Already running!')
 
# иначе делаем полезную работу
# например, немного ждём
else:
    import time
    print('Sleep...')
    time.sleep(10)
    print('Exit!')

Добавить комментарий
0

к примеру, можно блокировать сам файл со скриптом (ну, чтоб не заводить отдельных файлов) с помощью функции flock() из fcntl:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
import fcntl, sys, os
from time import sleep
 
fp = open(os.path.realpath(__file__), 'r')
 
try:
    fcntl.flock(fp, fcntl.LOCK_EX | fcntl.LOCK_NB)
except IOError:
    print('неужели другой мой экземпляр всё ещё работает?')
    sys.exit(0)
 
print('я единственный и неповторимый!!11')
sleep(2)


проверка.

если между запуском первого и второго экземпляра меньше двух секунд (время работы первого экземпляра), то второй (третий…) экземпляр получит исключение при попытке блокировки:

$ ./s.py & sleep 1; ./s.py
[1] 26327
я единственный и неповторимый!!11
неужели другой мой экземпляр всё ещё работает?

если же больше, то оба запуска пройдут успешно:

$ ./s.py & sleep 3; ./s.py
[1] 26382
я единственный и неповторимый!!11
[1]+  Done                    ./s.py
я единственный и неповторимый!!11

Добавить комментарий
Напишите свой ответ на данный вопрос.
Scroll Up