Sin SIGTERM antes de SIGKILL/apagado con systemd en Ubuntu 16.04

Sin SIGTERM antes de SIGKILL/apagado con systemd en Ubuntu 16.04

Me encontré con este problema mientras intentabaresponder una pregunta en Stackoverflow.

Al apagar, Ubuntu 12.04 envía SIGTERMa todos los procesos y espera como máximo 10 segundos antes de eliminarlos SIGKILL(a menos que hayan terminado antes). Mi respuesta sobre SO incluso contiene un script de Python que verifica ese comportamiento. El script se inicia en una terminal, se envía a un segundo plano y luego la terminal lo rechaza. Al recibirlo SIGTERM, el script continúa e imprime continuamente en un archivo cuánto tiempo ha estado ejecutándose.despuésrecibiendo SIGTERM.

Sin embargo, en Ubuntu 16.04, el script se elimina inmediatamente después del apagado (no SIGTERMse registra).

Busqué en Google por un tiempo, pero no pude encontrar nada útil. ¿Nadie se ha encontrado nunca con ese cambio importante para la versión actual de LTS?

Aquí está el guiónsignaltest.py

import signal
import time

stopped = False

out = open('log.txt', 'w')

def stop(sig, frame):
    global stopped
    stopped = True
    out.write('caught SIGTERM\n')
    out.flush()

signal.signal(signal.SIGTERM, stop)

while not stopped:
    out.write('running\n')
    out.flush()
    time.sleep(1)

stop_time = time.time()
while True:
    out.write('%.4fs after stop\n' % (time.time() - stop_time))
    out.flush()
    time.sleep(0.1)

El script utiliza el archivo log.txten el directorio actual para todos los resultados. Tiene un bucle que imprime "en ejecución" cada segundo. La recepción SIGTERMrompe el ciclo y comienza otro ciclo que imprime los segundos transcurridos desde la recepción SIGTERM.

El script se ejecuta desde una terminal separada usando disown:

python signaltest.py &
disown

Para ser claro:Esto no es un duplicado deUbuntu no envía SIGTERM al cerrar. La pregunta es sobre aplicaciones de escritorio y las respuestas tampoco cuadran.

Respuesta1

systemd (a diferencia del advenedizo en versiones anteriores de Ubuntu) también envía SIGHUP al apagar (y espera 90 segundos en lugar de 10 segundos antes de enviar SIGKILL). Sugiero ignorar SIGHUPo manejar SIGTERMde SIGHUPla misma manera (idempotente).

El script de prueba modificado podría cambiarse así:

import signal
import time

stopped = False

out = open('log.txt', 'w')

def stop(sig, frame):
    global stopped
    stopped = True
    out.write('caught SIGTERM\n')
    out.flush()

def ignore(sig, frsma):
    out.write('ignoring signal %d\n' % sig)
    out.flush()

signal.signal(signal.SIGTERM, stop)
signal.signal(signal.SIGHUP, ignore)

while not stopped:
    out.write('running\n')
    out.flush()
    time.sleep(1)

stop_time = time.time()
while True:
    out.write('%.4fs after stop\n' % (time.time() - stop_time))
    out.flush()
    time.sleep(0.1)

información relacionada