2010-03-30 36 views
19

我試圖在Process中使用atexit,但不幸的是它似乎不起作用。下面是一些示例代碼:Python進程不會調用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 

我希望,當a.terminate()b.terminate()被稱爲W.run.log_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上下文)何時Process終止?

感謝您的意見 - 非常感謝。

解決方案

編輯:基於由Alex馬爾泰利建議的解決方案,如預期了以下工作:

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文檔中的以下評論:

注意:當程序被信號終止,檢測到Python致命內部錯誤或調用os._exit()時,不會調用通過此模塊註冊的函數。

回答

17

由於the docs說,

在Unix上使用SIGTERM 信號進行;在Windows上使用TerminateProcess() 。注意退出處理程序和 finally子句等,將不會被執行 。

如果你在Unix上,你應該能夠攔截SIGTERMsignal,並執行任何「終止活動,」你需要;但是,我不知道跨平臺解決方案。