2009-08-06 26 views
6

मैं इस देख रहा हूँ जब मैं प्रेस Ctrl-C मेरे ऐपपायथन Multiprocessing बाहर निकलने त्रुटि

Error in atexit._run_exitfuncs: 
Traceback (most recent call last): 
    File "/usr/lib/python2.6/atexit.py", line 24, in _run_exitfuncs 
    func(*targs, **kargs) 
    File "/usr/lib/python2.6/multiprocessing/util.py", line 269, in _exit_function 
    p.join() 
    File "/usr/lib/python2.6/multiprocessing/process.py", line 119, in join 
    res = self._popen.wait(timeout) 
    File "/usr/lib/python2.6/multiprocessing/forking.py", line 117, in wait 
    return self.poll(0) 
    File "/usr/lib/python2.6/multiprocessing/forking.py", line 106, in poll 
    pid, sts = os.waitpid(self.pid, flag) 
OSError: [Errno 4] Interrupted system call 
Error in sys.exitfunc: 
Traceback (most recent call last): 
    File "/usr/lib/python2.6/atexit.py", line 24, in _run_exitfuncs 
    func(*targs, **kargs) 
    File "/usr/lib/python2.6/multiprocessing/util.py", line 269, in _exit_function 
    p.join() 
    File "/usr/lib/python2.6/multiprocessing/process.py", line 119, in join 
    res = self._popen.wait(timeout) 
    File "/usr/lib/python2.6/multiprocessing/forking.py", line 117, in wait 
    return self.poll(0) 
    File "/usr/lib/python2.6/multiprocessing/forking.py", line 106, in poll 
    pid, sts = os.waitpid(self.pid, flag) 
OSError: [Errno 4] Interrupted system call 

मैं अपने खुद के सामान की चोटी पर मुड़ उपयोग कर रहा हूँ बाहर निकलने के लिए,

मैं संकेत Ctrl-C पंजीकृत निम्न कोड के साथ

def sigHandler(self, arg1, arg2): 
     if not self.backuped: 
      self.stopAll() 
     else: 
      out('central', 'backuped ALREADY, now FORCE exiting') 
      exit() 


    def stopAll(self): 
     self.parserM.shutdown() 
     for each in self.crawlM: 
      each.shutdown() 
     self.backup() 
     reactor.stop() 

और जब वे बंद करने के लिए दूसरों का संकेत है, यह

के माध्यम से बंद अच्छी तरह से करने के लिए उन्हें बताने की कोशिश करता
exit = multiprocessing.Event() 
def shutdown(self): 
    self.exit.set() 

जहाँ मेरे सभी प्रक्रियाओं किसी रूप में कर रहे हैं,

def run(self): 
    while not self.exit.is_set(): 
     do something 
    out('crawler', 'crawler exited sucessfully') 

किसी भी विचार इस त्रुटि क्या है? मुझे केवल तब मिलता है जब मेरे पास किसी विशेष थ्रेड के एक से अधिक उदाहरण होते हैं।

उत्तर

5

यह इंटरैक्शन ओएस सिस्टम कॉल, सिग्नल और मल्टीप्रोसेसिंग मॉड्यूल में इसे कैसे प्रबंधित किया जाता है, से संबंधित है। मुझे सच में यकीन नहीं है कि यह एक बग या फीचर है, लेकिन यह कुछ मुश्किल क्षेत्र में है क्योंकि यह वह जगह है जहां पायथन ओएस से मिलता है।

समस्या यह है कि मल्टीप्रोसेसिंग प्रतीक्षापिड पर अवरुद्ध हो रही है जब तक कि वह जिस बच्चे की प्रतीक्षा नहीं कर रहा है। हालांकि, चूंकि आपने सिगिनट के लिए एक सिग्नल हैंडलर स्थापित किया है और आपके प्रोग्राम को यह संकेत मिलता है, यह आपके सिग्नल हैंडलर को निष्पादित करने के लिए सिस्टम कॉल में बाधा डालता है, और प्रतीक्षापिट निकलता है जो इंगित करता है कि यह सिग्नल द्वारा बाधित था। जिस तरह से पाइथन इस मामले को संभालता है वह अपवादों से होता है।

समाधान के लिए, आप थोड़ी देर के पाश में हमलावर खंड (रों) संलग्न कर सकते हैं और कोशिश इस तरह ब्लॉक/पकड़, या तो चारों ओर जहां इंतजार धागे खत्म करने के लिए के लिए, या उपवर्ग multiprocessing.Popen:

import errno 
from multiprocessing import Process 

p = Process(target=func, args=stuff) 
p.start() 
notintr = False 
while not notintr: 
    try: 
    p.join() # "Offending code" 
    notintr = True 
    except OSError, ose: 
    if ose.errno != errno.EINTR: 
     raise ose 

multiprocessing.forking.Popen साथ के बारे में mucking के लिए आप कुछ इस तरह कर दिया था:

import errno 
from multiprocessing import Process 
from multiprocessing.forking import Popen 
import os 

# see /path/to/python/libs/multiprocessing/forking.py 
class MyPopen(Popen): 
    def poll(self, flag=os.WNOHANG): # from forking.py 
    if self.returncode is None: # from forking.py 
     notintr = False 
     while not notintr: 
     try: 
      pid, sts = os.waitpid(self.pid, flag) # from forking.py 
      notintr = True 
     except OSError, ose: 
      if ose.errno != errno.EINTR: 
      raise ose 
     # Rest of Popen.poll from forking.py goes here 

p = Process(target=func args=stuff) 
p._Popen = p 
p.start() 
p.join() 
+0

वाह वास्तव में बहुत अच्छा था। कोई भी अच्छा संसाधन ऑनलाइन जो ऐसी गहराई से कुछ समझाएगा? –

0

मैं यह देख रहा था, लेकिन यह दूर चला गया जब मैं अपने खुद के साथ संकेत संचालकों overrode। रिएक्टर.रुन (installSignalHandlers = गलत) का उपयोग करें और SIGINT, SIGTERM, आदि के लिए अपने स्वयं के कार्यों को परिभाषित करें

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