Обеспечение выполнения только одного процесса для длительного процесса с использованием Python - PullRequest
1 голос
/ 06 марта 2012

Я ищу наилучшую практику для обеспечения того, чтобы скрипт, выполняемый заданием cron каждую минуту, имел только один работающий экземпляр.Например, если у меня есть cron, который выполняется каждую минуту, и если процесс занимает больше одной минуты, тогда не выполняйте другую до завершения.

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

Я помещаю код поверх файла.Это работает, но опять грязно.

def doRunCount(stop=False,min_run=1):
    import inspect
    current_file = inspect.getfile( inspect.currentframe() )
    print current_file
    fn = current_file.split()
    run_check = os.popen('ps aux | grep python').read().strip().split('\n')
    run_count = 0
    for i in run_check:
        if i.find('/bin/sh')<0:
            if i.find(current_file)>=0:
                run_count = run_count + 1
    if run_count>min_run:
        print 'max proccess already running'
        exit()
    return run_count

1 Ответ

2 голосов
/ 06 марта 2012

Я не знаю, можете ли вы описать это как лучшую практику, но я бы использовал файл pid. Вот фрагмент, аналогичный тому, который я использовал несколько раз, чтобы убедиться, что запущен только один экземпляр определенного приложения.

import os, sys

PID_FILE = '/path/to/somewhere.pid'

if os.path.exists( PID_FILE ):
    pid = int(open( PID_FILE,'rb').read().rstrip('\n'))
    if len(os.popen('ps %i' % pid).read().split('\n')) > 2:
        print "Already Running as pid: %i" % pid
        sys.exit(1)
# If we get here, we know that the app is not running so we can start a new one...
pf = open(PID_FILE,'wb')
pf.write('%i\n' % os.getpid())
pf.close()

if __name__ == '__main__':
    #Do something here!
    pass

Как я уже сказал, это похоже на то, что я использовал, но я просто переписал этот фрагмент, чтобы быть немного более элегантным. Но это должно объяснить общую концепцию! Надеюсь, это поможет.

Вот небольшая модификация, которая должна устранить любые проблемы, возникающие в результате сбоя процесса. Этот код не только подтвердит, что файл pid существует, но и, что pid в файле все еще жив и что pid остается тем же исполняемым файлом.

import os, sys

PID_FILE = '/path/to/somewhere.pid'

if os.path.exists( PID_FILE ):
    pid = int(open( PID_FILE,'rb').read().rstrip('\n'))
    pinfo = os.popen('ps %i' % pid).read().split('\n')
    if len( pinfo ) > 2:
        # You might need to modify this to your own usage...
        if pinfo[1].count( sys.argv[0] ):
            # Varify that the process found by 'ps' really is still running...
            print "Already Running as pid: %i" % pid
        sys.exit(1)
# If we get here, we know that the app is not running so we can start a new one...
pf = open(PID_FILE,'wb')
pf.write('%i\n' % os.getpid())
pf.close()

if __name__ == '__main__':
    #Do something here!
    pass

После этого я просто оставляю файл pid, так как вам не нужно беспокоиться о ложном срабатывании. Обратите внимание, что вам может потребоваться изменить второй этап проверки в соответствии с вашими конкретными потребностями!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...