Ответ
Это два разных сигнала, используемых для завершения процессов в Unix-подобных системах, но они работают принципиально по-разному.
kill -15
(SIGTERM)
- "Вежливый" запрос на завершение. Это сигнал по умолчанию для утилиты
kill
. Он сообщает процессу, что его просят завершиться. - Можно перехватить. Приложение может (и должно) перехватить этот сигнал, чтобы выполнить очистку: сохранить данные, закрыть файлы и сетевые соединения, завершить дочерние процессы.
- Может быть проигнорирован. Процесс может проигнорировать
SIGTERM
, если он занят или некорректно написан.
kill -9
(SIGKILL)
- Принудительное "убийство". Этот сигнал нельзя перехватить, заблокировать или проигнорировать.
- Немедленное завершение. Ядро системы немедленно останавливает выполнение процесса, не давая ему шанса на очистку.
- Опасность. Использование
SIGKILL
может привести к повреждению данных, оставленным "зомби"-процессам и утечкам ресурсов (например, временные файлы не будут удалены).
Пример перехвата SIGTERM
в Go:
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"time"
)
func main() {
// Создаем канал для получения сигналов ОС
sigChan := make(chan os.Signal, 1)
// Уведомляем наш канал о поступлении SIGINT или SIGTERM
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
fmt.Println("Процесс запущен (PID: ", os.Getpid(), "). Ожидание сигнала...")
// Блокируемся, пока не получим сигнал
sig := <-sigChan
fmt.Printf("nПолучен сигнал: %s. Начинаю корректное завершение...n", sig)
// Здесь происходит логика очистки
fmt.Println("Закрываю соединения, сохраняю состояние...")
time.Sleep(2 * time.Second)
fmt.Println("Работа завершена.")
}
Итог: Всегда следует сначала отправлять SIGTERM
и давать процессу время на завершение. SIGKILL
— это крайняя мера, которую стоит применять, только если процесс не отвечает на SIGTERM
.