2010-03-30 12 views
19

पर कॉल नहीं करेगी, मैं में atexit का उपयोग करने का प्रयास कर रहा हूं, लेकिन दुर्भाग्य से यह काम नहीं कर रहा है।पायथन प्रक्रिया atexit

import time 
import atexit 
import logging 
import multiprocessing 

logging.basicConfig(level=logging.DEBUG) 

class W(multiprocessing.Process): 
    def run(self): 
     logging.debug("%s Started" % self.name) 

     @atexit.register 
     def log_terminate(): 
      # ever called? 
      logging.debug("%s Terminated!" % self.name) 

     while True: 
      time.sleep(10) 

@atexit.register 
def log_exit(): 
    logging.debug("Main process terminated") 

logging.debug("Main process started") 

a = W() 
b = W() 
a.start() 
b.start() 
time.sleep(1) 
a.terminate() 
b.terminate() 

इस कोड के उत्पादन में किया जाता है::

 
DEBUG:root:Main process started 
DEBUG:root:W-1 Started 
DEBUG:root:W-2 Started 
DEBUG:root:Main process terminated 

मैं उम्मीद करेंगे कि W.run.log_terminate() जब a.terminate() और b.terminate() कहा जाता है कहा जाता है, और उत्पादन likeso कुछ होने (यहां कुछ उदाहरण कोड है जोर जोड़ा) !:

 
DEBUG:root:Main process started 
DEBUG:root:W-1 Started 
DEBUG:root:W-2 Started 
DEBUG:root:W-1 Terminated! 
DEBUG:root:W-2 Terminated! 
DEBUG:root:Main process terminated 

क्यों इस काम नहीं कर रहा है, और वहाँसे एक संदेश (लॉग इन करने के लिए एक बेहतर तरीका हैसंदर्भ) जब एक Process समाप्त कर दिया गया है?

आपके इनपुट के लिए धन्यवाद - इसकी बहुत सराहना की गई है।

समाधान

संपादित करें: एलेक्स मार्टेली ने सुझाव दिया समाधान के आधार पर, उम्मीद के रूप में निम्नलिखित काम करता है:

:

import sys 
import time 
import atexit 
import signal 
import logging 
import multiprocessing 

logging.basicConfig(level=logging.DEBUG) 

class W(multiprocessing.Process): 
    def run(self): 
     logging.debug("%s Started" % self.name) 

     def log_terminate(num, frame): 
      logging.debug("%s Terminated" % self.name) 
      sys.exit() 
     signal.signal(signal.SIGTERM, log_terminate) 
     while True: 
      time.sleep(10) 

@atexit.register 
def log_exit(): 
    logging.debug("Main process terminated") 

logging.debug("Main process started") 
a = W() 
b = W() 
a.start() 
b.start() 
time.sleep(1) 
a.terminate() 
b.terminate() 

यह atexit दस्तावेज में निम्नलिखित टिप्पणी नोट करने के लिए फ़ायदेमंद हो सकता है नोट: इस मॉड्यूल के माध्यम से पंजीकृत कार्यों को कॉल नहीं किया जाता है जब प्रोग्राम सिग्नल द्वारा मारा जाता है, जब एक पाइथन घातक आंतरिक त्रुटि का पता लगाया जाता है, या जब os._exit() कहा जाता है।

उत्तर

17

the docs कहना के रूप में,

यूनिक्स पर इस SIGTERM संकेत का प्रयोग किया जाता है; विंडोज टर्मिनेट प्रोसेस पर() का उपयोग किया जाता है। ध्यान दें कि बाहर निकलने वाले हैंडलर और अंततः खंड, आदि, निष्पादित नहीं होंगे।

आप यूनिक्स पर हैं, तो आप signal साथ सक्षम अवरोधन SIGTERM होना चाहिए, और जो कुछ भी "समाप्ति गतिविधियों" आप की जरूरत करते हैं; हालांकि, मुझे क्रॉस-प्लेटफ़ॉर्म समाधान की जानकारी नहीं है।