2012-03-06 27 views
1

我正在尋找最佳實踐來確保每分鐘執行的腳本腳本只有一個運行實例。對於例如如果我有一個每分鐘執行一次的cron,並且萬一這個過程需要更長的時間然後一分鐘,那麼不要再執行另一個。確保只有一個進程爲使用python的長時間運行的進程執行

現在我有以下功能。實質上,我得到當前進程的名稱,並執行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 
+0

這聽起來像你正試圖避免資源競爭條件。爲什麼不直接通過確保cron作業是原子解決問題?也許描述他們在做什麼的性質。 – HeyWatchThis 2012-03-06 04:22:56

+0

只需編寫一個PID文件並檢查它是否存在。請參閱http://stackoverflow.com/questions/788411/check-to-see-if-python-script-is-running – 2012-03-06 04:43:12

+0

但是如果進程崩潰並且存在一個現有的pid,並且進程沒有時間刪除pid? – Tampa 2012-03-06 05:52:43

回答

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文件,因爲你不需要擔心誤報。請注意,您可能需要將驗證的第二步修改爲您自己的特定用法!

+0

我喜歡這個方法,但是現在好奇於一個永遠不會被刪除的揮之不去的問題 – Tampa 2012-03-06 05:54:31

+0

我發佈了第二個版本,應該回答您的一些擔憂。基本上,我盡我所能來驗證pid文件中的進程是否真的死了。之後,pid文件的存在是一個非問題! – 2012-03-06 06:14:26

+0

Thnaks,當我運行你的代碼時,我得到這個錯誤。 pf.write('%i \ n'%pid) NameError:name'pid'is not defined – Tampa 2012-03-07 01:25:02

相關問題