2011-07-19 15 views
5

PLAZO Tengo un ejemplo sencillo:programa de trenzado y la señal

 
    from twisted.internet import utils,reactor 

    def test: 
     utils.getProcessOutput(executable="/bin/sleep",args=["10000"]) 

    reactor.callWhenRunning(test) 
    reactor.run() 

cuando envío de señales "término" programa "sueño" continúa siendo llevado a cabo, al pulsar Ctrl-C en el teclado "del sueño "deteniéndose". (Ctrl-C no es señal equivalente TERM?) ¿Por qué? ¿Cómo matar "dormir" después de enviar la señal "TERM" a este programa?

Respuesta

4

Ctrl-C envía SIGINT a todo el grupo de procesos en primer plano. Eso significa que se envía a su programa Twisted y al proceso hijo dormido.

Si quieres matar el proceso de letargo, siempre que el proceso de Python va a salir, entonces es posible que desee un antes de la parada gatillo:

def killSleep(): 
    # Do it, somehow 

reactor.addSystemEventTrigger('before', 'shutdown', killSleep) 

medida que su código de ejemplo está escrito, killSleep es difícil implementar. getProcessOutput no le proporciona algo que permita matar fácilmente al niño (por ejemplo, no conoce su pid). Si usa reactor.spawnProcess y ProcessProtocol personalizado, este problema se resuelve: el ProcessProtocol se conectará a un transporte de proceso que tiene un método signalProcess que puede usar para enviar un SIGTERM (o lo que quiera) al proceso hijo.

También puede ignorar SIGINT y este punto de forma manual y luego entregarlo a todo el grupo de procesos:

import os, signal 

def killGroup(): 
    signal.signal(signal.SIGINT, signal.SIG_IGN) 
    os.kill(-os.getpgid(os.getpid()), signal.SIGINT) 

reactor.addSystemEventTrigger('before', 'shutdown', killGroup) 

Ignorar SIGINT debido a que el proceso de trenzado ya se está cerrando y otra señal no va a hacer ningún bien (y probablemente lo confunda o al menos conduzca a la notificación de errores espurios). Enviar una señal al -os.getpgid(os.getpid()) es cómo enviarlo a todo su grupo de procesos.

Cuestiones relacionadas