2011-05-27 24 views
15

Her dakika bir python betiği (job.py) çalıştırmam gerekiyor. Bu betik zaten çalışıyorsa başlatılmamalıdır. Yürütme süresi 10 saniye ile birkaç saat arasında olabilir. Python betiğini sadece cron ile çalıştırıyorsanız

Yani benim crontab'ınıza içine koyun:

* * * * * root cd /home/lorenzo/cron && python -u job.py 1>> /var/log/job/log 2>> /var/log/job/err 

Ben sürüsü kullanmak, zaten çalışırken senaryoyu başlayan önlemek için().

import fcntl 
import time 
import sys 

def doIncrediblyImportantThings(): 
    for i in range (100): 
     sys.stdout.write ('[%s] %d.\n' % (time.strftime ('%c'), i)) 
     time.sleep (1) 

if __name__ == '__main__': 
    f = open ('lock', 'w') 
    try: fcntl.lockf (f, fcntl.LOCK_EX | fcntl.LOCK_NB) 
    except: 
     sys.stderr.write ('[%s] Script already running.\n' % time.strftime ('%c')) 
     sys.exit (-1) 
    doIncrediblyImportantThings() 

Bu yaklaşım iş gibi görünüyor:

Bu

komut dosyası (job.py) 'dir.

Eksik olduğum bir şey var mı? Bu yaklaşımı kullanarak karşılaşabileceğim herhangi bir sıkıntı var mı?

fazlası var tavsiye veya bu davranışı elde etme "doğru" yolu var mı?

Herhangi bir öneriniz için teşekkür ederim.

+0

Büyük soru. – erjoalgo

cevap

9

tek öneri istisna biraz daha belirgin taşıma yapmaktır. Yanlışlıkla bir günde fcntl içe aktarma işlemini silmek istemezsiniz ve bu sonuçları NameError gizleyin. Her zaman, işlemek istediğiniz en özel özel durumu yakalamaya çalışın. Kilit elde edilemez olmanın herhangi diğer neden (muhtemelen cron'u kullandığınız beri epostanızda) gösterir

import errno 

try: 
    fcntl.lock(...) 
except IOError, e: 
    if e.errno == errno.EAGAIN: 
     sys.stderr.write(...) 
     sys.exit(-1) 
    raise 

Bu şekilde ve bir şey olmadığına karar verebilirsiniz: Bu durumda, şöyle bir şey önermek bir yöneticinin bakması için, programın ele alınacağı başka bir durum veya başka bir şey. Bitirdin önceki örneği sonra bir komut dosyası x saniye yeniden başlayacaktır bir servistir, bu nedenle aynı senaryonun örtüşen örneklerini asla hangi The Fat Controller kullanabilirsiniz

+0

Teşekkür ederim. İyi bir nokta. – Hyperboreus

2

makine yeniden başlatılır veya komut dosyası çalıştıran (ve dolayısıyla aktif bir kilidi) ile donduğunda Sen belada. Bunu karşılamanın basit bir yolu, rm /path/to/lock'u çalıştırmak için @reboot cron zaman damgasını kullanmaktır. Ben yapacak

+0

Çok teşekkür ederim. Bunu dikkate alacağım. Dosya yeniden başlatma ile kalıcı kilitleniyor mu?Kullanmakta olduğum dosya sistemine bağlı (aslında ext4)? – Hyperboreus

+2

Dosya kilitleri, yeniden başlatmalarda kalıcı değil. İşlemleri yeniden başlatırken kalıcı bile değiller, bu nedenle kodunuzdaki kilidi serbest bırakmak zorunda kalmazsınız - işlem sonlandırıldığında serbest kalır. –

+0

@ Jean-Paul Bu, Mel durumları gibi yeniden başlatma ve donma konusunda endişem yok anlamına mı geliyor? – Hyperboreus

0

.

Hatta ayar hemen sonra belli bir koşul gerçekleştiğinde bir örneğini başlatmak için olabilir.

(Korkarım ki web sitesi biraz basit, ama proje kararlı ve benim bildiğim son birkaç web sitesinde çalışıyor. Ben v0.0.3 dışarı olsun güzel, güzel bir web sitesi yapacağım kapı!)

+0

Giriş için teşekkürler. Ama ben senin kod kullanmak sanırım aslında ihtiyacım olandan çok daha fazla işlevsellik (paralel yürütme vb) getiriyor gibi topları ile kuşlarda çekim gibi olurdu. – Hyperboreus

2

geçen hafta tam olarak bu sorun koştu ve bazı iyi çözümler bulmak her ne kadar, çok basit ve temiz bir piton paketi yapmaya karar verdi ve PyPI yüklerken. son derece basittir kullanma pip install quicklock

:

ile takın

[[email protected] ~/live] python 
Python 2.7.6 (default, Sep 9 2014, 15:04:36) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.39)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> from quicklock import singleton 
>>> # Let's create a lock so that only one instance of a script will run 
... 
>>> singleton('hello world') 
>>> 
>>> # Let's try to do that again, this should fail 
... 
>>> singleton('hello world') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/Users/nate/live/gallery/env/lib/python2.7/site-packages/quicklock/quicklock.py", line 47, in singleton 
    raise RuntimeError('Resource <{}> is currently locked by <Process {}: "{}">'.format(resource, other_process.pid, other_process.name())) 
RuntimeError: Resource <hello world> is currently locked by <Process 24801: "python"> 
>>> 
>>> # But if we quit this process, we release the lock automatically 
... 
>>> ^D 
[[email protected] ~/live] python 
Python 2.7.6 (default, Sep 9 2014, 15:04:36) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.39)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> from quicklock import singleton 
>>> singleton('hello world') 
>>> 
>>> # No exception was thrown, we own 'hello world'! 

bir göz atın: https://pypi.python.org/pypi/quicklock

İlgili konular