2011-05-27 12 views
15

नहीं चल रहा है मुझे हर मिनट एक पायथन स्क्रिप्ट (job.py) चलाने की आवश्यकता है। यह स्क्रिप्ट शुरू नहीं होनी चाहिए यदि यह पहले से चल रहा है। इसका निष्पादन समय 10 सेकंड और कई घंटों के बीच हो सकता है।क्रॉन के साथ पाइथन स्क्रिप्ट चलाना केवल

तो मैं अपने crontab में डाल दिया:

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

स्क्रिप्ट शुरू कर जब यह पहले से ही चल रहा है से बचने के लिए, मैं झुंड का उपयोग()।

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() 

यह दृष्टिकोण काम करने के लिए लगता है:

यह स्क्रिप्ट (job.py) है।

क्या मुझे कुछ भी याद आ रही है? क्या इस दृष्टिकोण का उपयोग करने में कोई समस्या है जो मैं चला सकता हूं?

क्या इस व्यवहार को प्राप्त करने के लिए अधिक सलाह दी गई है या "उचित" तरीके हैं?

मैं किसी भी सुझाव के लिए धन्यवाद।

+0

ग्रेट सवाल। – erjoalgo

उत्तर

9

एकमात्र सुझाव जो मैं करता हूं वह आपके अपवाद को थोड़ा और विशिष्ट बनाने के लिए करना है। आप fcntl को एक दिन आयात करने और NameError को गलती से छिपाना नहीं चाहते हैं। हमेशा उस विशिष्ट अपवाद को पकड़ने का प्रयास करें जिसे आप संभालना चाहते हैं। इस मामले में, मैं की तरह कुछ सुझाव देते हैं:

import errno 

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

इस तरह, किसी भी अन्य ताला नायाब होने का कारण पता चलता है (शायद अपने ईमेल के बाद से आप क्रॉन का उपयोग कर रहे में) और अगर यह कुछ आप तय कर सकते व्यवस्थापक को देखने के लिए, कार्यक्रम के लिए एक और मामला संभालने के लिए, या कुछ और।

+0

धन्यवाद। अच्छी बात। – Hyperboreus

2

जब मशीन रीबूट या स्क्रिप्ट चल रहा है (और इस प्रकार एक सक्रिय ताला) के साथ फ्रीज करता है तो आप परेशानी में हैं। इसका मुकाबला करने का सरल तरीका rm /path/to/lock चलाने के लिए @reboot क्रॉन टाइमस्टैम्प का उपयोग करना है।

+0

बहुत बहुत धन्यवाद। मैं इसे ध्यान में रखूंगा। क्या फाइल लॉक रीबूट के माध्यम से लगातार हैं?इस फ़ाइल सिस्टम पर निर्भर करता है जिसका मैं उपयोग कर रहा हूं (वास्तव में ext4)? – Hyperboreus

+2

फ़ाइल ताले रीबूट में लगातार नहीं हैं। वे प्रक्रियाओं को पुनरारंभ करने में भी लगातार नहीं हैं, यही कारण है कि आपको अपने कोड में लॉक जारी करने की आवश्यकता नहीं है - प्रक्रिया समाप्त होने पर इसे जारी किया जाता है। –

+0

@ जीन-पॉल इसका मतलब है कि मुझे मेल स्टेटस के रूप में रिबूट और फ्रीज के बारे में चिंता करने की ज़रूरत नहीं है? – Hyperboreus

0

आप The Fat Controller का उपयोग कर सकते हैं जो एक डिमन है जो पिछले उदाहरण समाप्त होने के बाद एक स्क्रिप्ट x सेकंड को पुनरारंभ करेगा, ताकि आप एक ही स्क्रिप्ट के ओवरलैपिंग उदाहरण कभी नहीं प्राप्त कर सकें।

यदि आप किसी निश्चित स्थिति को पूरा करते हैं तो तुरंत बाद में एक उदाहरण शुरू करने के लिए इसे ट्यून भी कर सकते हैं।

(मुझे डर है कि वेबसाइट थोड़ा बुनियादी है, लेकिन परियोजना स्थिर है और आखिरी कई वेबसाइटों पर चल रही है जो मुझे पता है। मैं एक अच्छा, सुंदर वेबसाइट बनाउंगा जब मैं v0.0.3 प्राप्त करता हूं दरवाजा!)

+0

इनपुट के लिए धन्यवाद। लेकिन मुझे लगता है कि आपके कोड का उपयोग करना पक्षियों के साथ पक्षियों पर शूटिंग की तरह थोड़ा सा होगा क्योंकि यह वास्तव में मुझे आवश्यकतानुसार बहुत अधिक कार्यक्षमता (समांतर निष्पादन आदि) लाता है। – Hyperboreus

2

मैं पिछले हफ्ते इस सटीक समस्या में भाग गया, और हालांकि मुझे कुछ अच्छे समाधान मिल गए, मैंने एक बहुत ही सरल और साफ पायथन पैकेज बनाने का फैसला किया और इसे पीपीपीआई पर अपलोड किया। यह अत्यंत सरल है का उपयोग करना pip install quicklock

:

साथ स्थापित

[[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'! 

एक नज़र डालें: https://pypi.python.org/pypi/quicklock

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^