Ubuntu 16.04에서 systemd를 사용하여 SIGKILL/종료 전에 SIGTERM이 없습니다.

Ubuntu 16.04에서 systemd를 사용하여 SIGKILL/종료 전에 SIGTERM이 없습니다.

시도하는 동안 이 문제가 발생했습니다.Stackoverflow에 대한 질문에 답변.

종료 시 Ubuntu 12.04는 SIGTERM모든 프로세스에 전송하고 최대 10초 동안 기다렸다가 종료합니다 SIGKILL(이전에 종료되지 않은 경우). SO에 대한 내 답변에는 해당 동작을 확인하는 Python 스크립트도 포함되어 있습니다. 스크립트는 터미널에서 시작되어 백그라운드로 전송되고 터미널에서 소유되지 않습니다. 을 수신하면 SIGTERM스크립트는 계속 진행되어 실행된 기간을 파일에 계속해서 인쇄합니다.~ 후에.SIGTERM

그러나 Ubuntu 16.04에서는 종료 시 스크립트가 즉시 종료됩니다( SIGTERM기록되지 않음).

잠시 구글링을 해봤지만 유용한 내용을 찾을 수 없었습니다. 현재 LTS 릴리스에서 이러한 주요 변경 사항을 본 사람은 아무도 없습니까?

스크립트는 다음과 같습니다.signaltest.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)

스크립트는 log.txt모든 출력에 대해 현재 디렉터리의 파일을 사용합니다. 매초마다 'running'을 인쇄하는 루프가 있습니다. 수신하면 SIGTERM루프가 중단되고 수신 이후 경과된 초를 인쇄하는 또 다른 루프가 시작됩니다 SIGTERM.

스크립트는 다음을 사용하여 분리된 터미널에서 실행됩니다 disown.

python signaltest.py &
disown

분명히 말하자면:이것은 다음의 중복이 아닙니다.우분투는 종료시 SIGTERM을 보내지 않습니다. 문제는 데스크톱 응용 프로그램에 관한 것이며 답변도 적합하지 않습니다.

답변1

systemd(이전 Ubuntu 버전의 upstart와 반대)는 종료 시 추가로 SIGHUP을 보냅니다(보내기 전에 10초 대신 90초를 기다립니다 SIGKILL). 나는 무시 하거나 동일한 (멱등성) 방식 으로 SIGHUP처리하는 것이 좋습니다.SIGTERMSIGHUP

수정된 테스트 스크립트는 다음과 같이 변경될 수 있습니다.

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)

관련 정보