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

使用python确保长时间运行的进程只执行一个进程,python,process,cron,Python,Process,Cron,我正在寻找最佳实践,以确保cron作业每分钟执行的脚本只有一个正在运行的实例。例如,如果我有一个每分钟执行一次的cron,如果这个过程需要更长的时间,那么在完成之前不要执行另一个cron 现在我有下面的函数。本质上,我得到了当前进程的名称,并进行了ps grep以查看是否列出了当前进程的计数。有点乱,所以我在寻找一种更像蟒蛇的方式 我将代码放在文件的顶部。它确实管用,但又很凌乱 def doRunCount(stop=False,min_run=1): import inspect

我正在寻找最佳实践,以确保cron作业每分钟执行的脚本只有一个正在运行的实例。例如,如果我有一个每分钟执行一次的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
def doRunCount(停止=False,最小运行=1):
进口检验
当前文件=inspect.getfile(inspect.currentframe())
打印当前文件
fn=当前_文件.split()
运行_check=os.popen('ps aux | grep python').read().strip().split('\n'))
运行计数=0
对于运行中的i\u检查:
如果i.find('/bin/sh')=0:
运行计数=运行计数+1
如果运行次数>最小运行次数:
打印“最大进程已在运行”
退出()
返回运行计数

我不知道您是否可以将此描述为最佳实践,但我会使用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文件,因为你真的不需要担心假阳性。注意:您可能需要根据自己的具体用途修改验证的第二步

听起来你是在试图避免资源竞争。为什么不直接通过确保cron作业是原子的来解决这个问题呢?也许描述一下他们正在做的事情的性质。只需编写一个PID文件并检查它是否存在。看到了吗,但是如果进程崩溃了,并且存在一个现有的pid,并且进程没有时间删除pid呢?我很喜欢这种方法,但现在对一个从未被删除的延迟pid感到好奇。对于crashI发布的第二个版本,应该可以回答您的一些问题。基本上,我会尽我所能来验证pid文件中的进程是否真的死了。之后,pid文件的存在就不再是问题了!Thnaks,当我运行你的代码时,我得到了这个错误。write(“%i\n”%pid)name错误:名称“pid”未定义。当我运行您的代码时,会出现此错误。pf.write(“%i\n”%pid)name错误:名称“pid”未定义行
pf.write(“%i\n”%pid)
应该是
pf.write(“%i\n”%os.getpid())
很抱歉!