2010-03-30 2 views
19

Process에 사용하고 있지만 불행히도 작동하지 않습니다.파이썬 프로세스가 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 종료 될 때?

입력 해 주셔서 감사합니다. 대단히 감사합니다.

솔루션

편집 : 알렉스 마르 텔리에 의해 제안 된 솔루션을 바탕으로, 다음 작품은 예상대로 :

:

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()가 호출 될 때 호출되지 않습니다. the docs 말하는 것처럼

답변

17

,

UNIX에서 이것은 SIGTERM 에게 신호를 이용하여 이루어진다; Windows에서 TerminateProcess() 이 사용됩니다. exit 핸들러와 finally 절 등은 이 실행되지 않습니다. 유닉스에 경우

, 당신은 signal과 함께 할 수 절편 SIGTERM, 그리고 "종단 활동"당신이 필요로하는 무엇이든 수행해야합니다; 그러나 크로스 플랫폼 솔루션에 대해서는 잘 모릅니다.

관련 문제