Почему я не могу завершить процесс SIGSTOP с помощью SIGTERM и где хранится ожидающий сигнал?

24

Я использую Debian stretch (systemd). Я управлял Rsyslog демоном на переднем плане , используя /usr/sbin/rsyslogd -n и я сделал Ctrl+ , Zчтобы остановить его. Состояние процесса изменилось на Tl(остановлено, нарезано). Я издал несколько команд для этого процесса, а также состояние процесса было то же самое: . Как только я сделал , он умер. У меня есть 3 вопроса.kill -15 <pid>Tlfg

  • Почему SIGSTOPпроцесс -ed не отвечает SIGTERM? Почему ядро ​​держит его в том же состоянии?
  • Почему он погиб, когда получил SIGCONTсигнал?
  • Если это было из-за предыдущего SIGTERMсигнала, где он хранился до возобновления процесса?
поЬир
источник

Ответы:

41

SIGSTOPи SIGKILLдва сигнала, которые не могут быть пойманы и обработаны процессом. SIGTSTPэто как SIGSTOPза исключением того, что он может быть пойман и обработан.

SIGSTOPИ SIGTSTPсигналы остановки процесса в своих направлениях, готовы к SIGCONT. Когда вы отправляете этот процесс a SIGTERM, процесс не выполняется и поэтому не может запустить код для выхода.

(Существуют также SIGTTINи SIGTTOU, которые являются сигналами, генерируемыми уровнем TTY, когда фоновое задание пытается прочитать или записать в терминал. Они могут быть перехвачены, но в противном случае остановят (приостановят) процесс, точно так же SIGTSTP. Но я сейчас иду игнорировать эти два до конца этого ответа.)

Вы CtrlZотправляете процесс a SIGTSTP, который, похоже, не обрабатывается каким-либо образом rsyslogd, поэтому он просто приостанавливает процесс в ожидании SIGCONTили SIGKILL.

Решение здесь также состоит в том, чтобы отправить SIGCONTза вами, SIGTERMчтобы процесс мог получать и обрабатывать сигнал.

Пример:

sleep 999 &

# Assume we got PID 456 for this process
kill -TSTP 456    # Suspend the process (nicely)
kill -TERM 456    # Terminate the process (nicely). Nothing happens
kill -CONT 456    # Continue the process so it can exit cleanly

Я думаю, что документация для библиотеки GNU C объясняет это довольно хорошо (мое выделение):

Пока процесс остановлен, никакие сигналы не могут быть доставлены до его продолжения , кроме SIGKILLсигналов и (очевидно) SIGCONTсигналов. Сигналы помечаются как ожидающие, но не доставляются, пока процесс не будет продолжен. Сигнал всегда вызывает прекращение процесса и не может быть заблокирован, обрабатывается или игнорируется. Вы можете игнорировать , но это всегда приводит к продолжению процесса, если он остановлен. Отправка сигнала процессу вызывает сброс всех ожидающих сигналов остановки для этого процесса. Аналогично, любые ожидающие сигналы для процесса отбрасываются, когда он получает сигнал остановкиSIGKILLSIGCONTSIGCONTSIGCONT

roaima
источник
1
@nohup. ответ расширен, но по сути, «да; он обработан, kill -15вы уже отправили».
Ройма
2
@ nohup да, согласно документации: « Пока процесс остановлен, никакие сигналы не могут быть доставлены на него, пока он не будет продолжен ... Сигналы помечаются как ожидающие, но не доставляются, пока процесс не будет продолжен. »
roaima
1
См. Также SIGTTIN и SIGTTOU, которые также останавливают процессы
Стефан Шазелас
1
@ StéphaneChazelas хорошая мысль. Я добавил упоминание об этом, но в остальном проигнорировал их. Пожалуйста, не стесняйтесь редактировать, как считаете нужным.
Ройма
2
@coteyr. Я не согласен: SIGKILLпредотвращает очистку приложения, поэтому использование SIGTERMпредпочтительнее во многих (большинстве) случаях.
Ройма
9

SIGTERMточно так же, как любой другой сигнал в том, что он может быть пойман процессом. Получение сигнала просто заставит процесс перейти к специальной процедуре обработки сигнала. Для SIGTERMдействия по умолчанию будет завершить процесс, но , например , редактор мог бы поймать сигнал , чтобы он мог сохранить черновик всех открытых файлов перед смертью. Если процесс остановлен, он не может запустить обработчик сигнала, но сигнал останется в ожидании, пока процесс не продолжится. Обратите внимание, что количество отправленных сигналов обычно не сохраняется.

Теоретически, система может знать, установлен ли для процесса обработчик сигнала SIGTERM, и немедленно прекратить его, если нет. Но (согласно комментарию Жиля) POSIX требует, чтобы сигнал ожидался до тех пор, пока процесс не будет продолжен SIGCONT.

ilkkachu
источник
4
Извините, мой предыдущий комментарий был неверным. Пока процесс остановлен, на него не поступают никакие сигналы, кроме SIGKILL и SIGCONT. Даже если сигнал имеет свое действие по умолчанию, которое должно завершить процесс, оно задерживается до тех пор, пока SIGCONT не возобновит процесс. POSIX предписывает это поведение.
Жиль "ТАК - перестань быть злым"