2010-03-30 21 views
19

Process numaralı telefondan atexit'u kullanmaya çalışıyorum ama maalesef işe yaramıyor.Python İşlemi atexit'i çağırmaz

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() 

Bu kodun çıktısı olan:

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

Ben a.terminate() ve b.terminate() çağrıldığında W.run.log_terminate() denilen olacağını beklenir ve çıkış likeso şey olmalı (Burada bazı örnek kod vurgu eklenmiştir) !:

 
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 

Neden bu çalışma değildir vebir mesaj (oturum açmak için daha iyi bir yol yokturbağlamı) Process sonlandırıldığında?

Girişiniz için teşekkür ederiz - çok beğeni topluyor.

Çözüm

DÜZENLEME: Alex Martelli önerdiği çözümü dayanarak, aşağıdaki işleri beklendiği gibi:

:

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() 

O atexit belgelerinde şu yorumu nota faydalıdır Not: Bu modül yoluyla kaydedilen fonksiyonlar, program bir sinyal tarafından öldürülürse, bir Python ölümcül dahili hata algılandığında veya os._exit() çağrıldığında çağrılmaz. the docs dediğimiz gibi

cevap

17

,

Unix üzerinde bu SIGTERM sinyal kullanılarak yapılır; Windows TerminateProcess() üzerinde kullanılır. Çıkış işleyicileri ve nihayetinde tümce, vb., yürütülmeyeceğini unutmayın. Eğer Unix sistemlerde

, sen signal ile mümkün yolunu kesmek SIGTERM olacak ve "sonlandırma faaliyetleri" ne gerek gerçekleştirmelisiniz; Ancak, çapraz platform çözümü bilmiyorum.