确保使用python仅对长时间运行的进程执行一个进程

时间:2012-03-06 04:15:25

标签: python process cron

我正在寻找最佳实践来确保每分钟由cron作业执行的脚本只有一个正在运行的实例。对于例如如果我有一个每分钟执行一次的cron,如果这个过程花费的时间超过一分钟,那么在完成之前不要执行另一个。

现在我有以下功能。本质上我得到了当前进程的名称,我做了一个ps grep来查看是否列出了当前进程的计数。有点凌乱所以我正在寻找一种更加pythonic的方式。

我将代码放在文件的顶部。它确实有效但又混乱了。

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 个答案:

答案 0 :(得分:2)

我不知道你是否可以将其描述为最佳做法,但我会使用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文件,因为你真的不需要担心误报。请注意,您可能需要根据自己的特定用途修改验证的第二步!