2009-08-31 20 views
5

जब एक अजगर डेमॉन प्रक्रिया के भीतर बहु मॉड्यूल का उपयोग कर रहा निम्न त्रुटि हो रही है (का उपयोग कर अजगर-डेमॉन):त्रुटि

 
Traceback (most recent call last): 
    File "/usr/local/lib/python2.6/atexit.py", line 24, in _run_exitfuncs 
    func(*targs, **kargs) 
    File "/usr/local/lib/python2.6/multiprocessing/util.py", line 262, in _exit_function 
    for p in active_children(): 
    File "/usr/local/lib/python2.6/multiprocessing/process.py", line 43, in active_children 
    _cleanup() 
    File "/usr/local/lib/python2.6/multiprocessing/process.py", line 53, in _cleanup 
    if p._popen.poll() is not None: 
    File "/usr/local/lib/python2.6/multiprocessing/forking.py", line 106, in poll 
    pid, sts = os.waitpid(self.pid, flag) 
OSError: [Errno 10] No child processes 

डेमॉन प्रक्रिया (अभिभावक) कई प्रक्रियाओं (बच्चों) को जन्म देता है और फिर समय-समय पर प्रक्रियाओं को यह देखने के लिए मतदान करता है कि वे पूरा कर चुके हैं या नहीं। यदि माता-पिता का पता चलता है कि प्रक्रियाओं में से एक पूरा हो गया है, तो यह उस प्रक्रिया को पुनरारंभ करने का प्रयास करता है। यह इस बिंदु पर है कि उपरोक्त अपवाद उठाया गया है। ऐसा लगता है कि प्रक्रियाओं में से एक बार पूरा होने पर, मल्टीप्रोसेसिंग मॉड्यूल से जुड़े किसी भी ऑपरेशन से यह अपवाद उत्पन्न होगा। यदि मैं एक गैर-डेमॉन पायथन स्क्रिप्ट में समान कोड चलाता हूं, तो यह किसी भी त्रुटि के साथ निष्पादित करता है।

संपादित करें:

नमूना स्क्रिप्ट

from daemon import runner 

class DaemonApp(object): 
    def __init__(self, pidfile_path, run): 
     self.pidfile_path = pidfile_path 
     self.run = run 

     self.stdin_path = '/dev/null' 
     self.stdout_path = '/dev/tty' 
     self.stderr_path = '/dev/tty' 

def run(): 
    import multiprocessing as processing 
    import time 
    import os 
    import sys 
    import signal 

    def func(): 
     print 'pid: ', os.getpid() 
     for i in range(5): 
      print i 
      time.sleep(1) 

    process = processing.Process(target=func) 
    process.start() 

    while True: 
     print 'checking process' 
     if not process.is_alive(): 
      print 'process dead' 
      process = processing.Process(target=func) 
      process.start() 
     time.sleep(1) 

# uncomment to run as daemon 
app = DaemonApp('/root/bugtest.pid', run) 
daemon_runner = runner.DaemonRunner(app) 
daemon_runner.do_action() 

#uncomment to run as regular script 
#run() 

उत्तर

4

की उपेक्षा कर SIGCLD भी साथ समस्याओं का कारण बनता: ​​- (समाप्त बच्चे की प्रक्रिया के लिए संकेत की अनदेखी करते हैं और माता-पिता प्रतीक्षा() डिफ़ॉल्ट व्यवहार)

सरल समाधान सिर्फ SIGCLD वापस SIG_DFL करने के लिए सेट करने के लिए है subprocess मॉड्यूल, उस मॉड्यूल में एक बग के कारण (issue 1731717, अभी भी 2011-09-21 के रूप में खुला है)।

यह व्यवहार version 1.4.8python-daemon लाइब्रेरी में संबोधित किया गया है; अब यह SIGCLD के साथ डिफ़ॉल्ट फिडलिंग को छोड़ देता है, इसलिए अब अन्य मानक लाइब्रेरी मॉड्यूल के साथ यह अप्रिय बातचीत नहीं है।

0

मुझे लगता है कि जो इस आप अजगर में अपनी स्क्रिप्ट चलाने की कोशिश कर सकते हैं के साथ मदद करनी चाहिए एक फिक्स ट्रंक और 2.6 maint में थोड़ी देर पहले डाल नहीं थी -ट्रंक या नवीनतम 2.6-रखरखाव svn? मैं बग जानकारी

+0

पायथन 2.7 ट्रंक के साथ स्क्रिप्ट चलाना एक ही परिणाम उत्पन्न करता है। मैंने मूल पोस्ट में उपयोग की जा रही टेस्ट स्क्रिप्ट जोड़ दी है। क्या मैं कुछ गलत कर रहा हूँ? –

+0

मुझे यकीन नहीं है, मुझे एक परीक्षण लोड करना होगा जो इसे जांचने के लिए पायथन-डिमन का उपयोग करता है। इस समय मुझ पर कुछ भी नहीं निकलता है। – jnoller

0

लग रहा है अपने त्रुटि की तरह अपने प्रक्रिया के अंत में आ रहा है ऊपर खींचने में नाकाम रहने रहा हूँ - अपने सुराग अपने ट्रैसबैक की शुरुआत में ही है, और मैं बोली ...:

File "/usr/local/lib/python2.6/atexit.py", line 24, in _run_exitfuncs 
    func(*targs, **kargs) 

यदि atexit._run_exitfuncs चल रहा है, तो यह स्पष्ट रूप से दिखाता है कि आपकी प्रक्रिया समाप्त हो रही है। इसलिए, त्रुटि स्वयं एक मामूली समस्या है - बस कुछ फ़ंक्शन से multiprocessing मॉड्यूल आपकी प्रक्रिया से "एट-एक्जिट" चलाने के लिए पंजीकृत है। वास्तव में दिलचस्प मुद्दा यह है कि, आपकी मुख्य प्रक्रिया क्यों निकल रही है? मुझे लगता है कि यह कुछ बेजोड़ अपवाद के कारण हो सकता है: अपवाद हुक सेट करने और अन्य अपवादों से गुम हो जाने से पहले समृद्ध नैदानिक ​​जानकारी दिखाने का प्रयास करें जो मल्टीप्रोसेसिंग के बाहर निकलने के लिए पंजीकृत है ...

+0

मैं एक try..except ब्लॉक में अपमानजनक बयान लपेटा जाता है और मैं जो निम्नलिखित ट्रैसबैक मिलती है: ( फ़ाइल "bugtest.py", रेखा 32, रन में अगर process.is_alive नहीं: Traceback (सबसे हाल कॉल पिछले)): फ़ाइल "/usr/local/lib/python2.6/multiprocessing/process.py", लाइन 132, is_alive self._popen.poll() फ़ाइल "/usr/local/lib/python2.6/ multiprocessing/forking.py ", लाइन 106, मतदान पिड, एसटीएस = ओ.वेटपिड (self.pid, ध्वज) ओएसईआरआर: [एरनो 10] कोई बच्चा –

+0

संसाधित नहीं करता मेरा अनुमान है कि मल्टीप्रोसेसिंग मॉड्यूल किसी भी तरह से असहमत है डेमन डबल-कांटा। दुर्भाग्यवश, मैं इस सामग्री को डीबग करने के लिए पर्याप्त रूप से समझ नहीं पा रहा हूं। –

0

I मैं पाइथन 2.6 के साथ आरएचईएल 5.3 के तहत अजवाइन वितरित कार्य प्रबंधक का उपयोग कर भी इसमें भाग रहा हूं। मेरे ट्रैस बैक थोड़ा अलग दिखता है, लेकिन त्रुटि एक ही:

 File "/usr/local/lib/python2.6/multiprocessing/pool.py", line 334, in terminate 
    self._terminate() 
    File "/usr/local/lib/python2.6/multiprocessing/util.py", line 174, in __call__ 
    res = self._callback(*self._args, **self._kwargs) 
    File "/usr/local/lib/python2.6/multiprocessing/pool.py", line 373, in _terminate_pool 
    p.terminate() 
    File "/usr/local/lib/python2.6/multiprocessing/process.py", line 111, in terminate 
    self._popen.terminate() 
    File "/usr/local/lib/python2.6/multiprocessing/forking.py", line 136, in terminate 
    if self.wait(timeout=0.1) is None: 
    File "/usr/local/lib/python2.6/multiprocessing/forking.py", line 121, in wait 
    res = self.poll() 
    File "/usr/local/lib/python2.6/multiprocessing/forking.py", line 106, in poll 
    pid, sts = os.waitpid(self.pid, flag) 
OSError: [Errno 10] No child processes 

काफी निराशा होती है .. मैं pdb के माध्यम से कोड चल रहा हूँ अब, लेकिन अभी तक कुछ भी देखा नहीं किया है।

0

मूल नमूना लिपि में "आयात संकेत" है लेकिन सिग्नल का कोई उपयोग नहीं है। हालांकि, मेरे पास इस त्रुटि संदेश के कारण एक स्क्रिप्ट थी और यह मेरे सिग्नल हैंडलिंग के कारण था, इसलिए अगर मैं दूसरों के लिए क्या हो रहा है तो मैं यहां समझाऊंगा। सिग्नल हैंडलर के भीतर, मैं प्रक्रियाओं के साथ सामान कर रहा था (उदाहरण के लिए एक नई प्रक्रिया बनाना)। जाहिर है यह काम नहीं करता है, इसलिए मैंने हैंडलर के भीतर ऐसा करना बंद कर दिया और त्रुटि को ठीक किया। (नोट: सिग्नल हैंडलिंग के बाद नींद() कार्य जागृत होते हैं ताकि यदि प्रक्रियाओं के साथ चीजों को करने की आवश्यकता हो तो सिग्नल पर कार्य करने का एक वैकल्पिक दृष्टिकोण हो सकता है)

5

आपकी समस्या डेमॉन और मल्टीप्रोसेसिंग मॉड्यूल के बीच एक संघर्ष है, विशेष रूप से एसआईजीसीएलडी (बाल प्रक्रिया समाप्त) सिग्नल के संचालन में। लॉन्च करते समय डिमन एसआईजीसीएलडी को SIG_IGN सेट करता है, जो कम से कम लिनक्स पर बच्चों को तुरंत समाप्त करने का कारण बनता है (जब तक पैरेंट प्रतीक्षा नहीं करता है तब तक ज़ोंबी बनने के बजाए)। लेकिन मल्टीप्रोसेसिंग का is_alive परीक्षण इंतजार करता है() यह देखने के लिए कि प्रक्रिया जीवित है या नहीं, जो विफल हो जाती है अगर प्रक्रिया पहले ही प्राप्त हो चुकी है।

def run(): 
    # ... 

    signal.signal(signal.SIGCLD, signal.SIG_DFL) 

    process = processing.Process(target=func) 
    process.start() 

    while True: 
     # ... 
+1

शब्दों का उपयोग करने के लिए बोनस प्वाइंट, 'समाप्त', 'reaped', 'zombie', और 'reaped' फिर से। –