Domanda

Sto cercando di utilizzare atexit in un Process, ma purtroppo non sembra funzionare. Ecco qualche esempio di codice:

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

L'output di questo codice è:

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

mi aspetterei che il W.run.log_terminate() sarebbe chiamato quando a.terminate() e b.terminate() sono chiamati, e l'uscita di essere qualcosa likeso (enfasi aggiunta):

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

Perché non è questo lavoro, e c'è un modo migliore per registrare un messaggio (dal contesto Process) quando un Process è terminato?

Grazie per l'ingresso - è molto apprezzato

.

Soluzione

EDIT: Sulla base di soluzione suggerita da Alex Martelli, le seguenti opere come previsto:

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

E 'utile sottolineare il seguente commento nella documentazione atexit:

Nota: le funzioni registrate tramite questo modulo non vengono chiamati quando il programma viene ucciso da un segnale, quando viene rilevato un errore fatale in Python, o quando os._exit () è chiamato
.
È stato utile?

Soluzione

la documentazione dicono,

  

In Unix questo viene fatto utilizzando il SIGTERM   segnale; su Windows TerminateProcess ()   viene utilizzato. Si noti che i gestori di uscita e   infine clausole, ecc, non sarà   eseguito.

Se sei su Unix, si dovrebbe essere in grado SIGTERM intercetta con segnale , ed eseguire qualunque 'attività di terminazione' è necessario; tuttavia, non so di una soluzione cross-platform.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top