Ответ
Это два разных сигнала, используемых для завершения процессов в 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.
Ответ 18+ 🔞
Ага, слушай, вот тебе на пальцах, как эти два сигнала работают, а то народ путает, как хуй с пальцем.
kill -15 (SIGTERM) — это вежливый стук в дверь
Представь, ты сидишь, кодишь, а тебе говорят: «Э, дружок, закругляйся, пожалуйста». Это 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 (Ctrl+C) или SIGTERM (kill -15) — шли сюда!»
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 (kill -15). Дай процессу пару секунд, пусть уйдёт с достоинством. А SIGKILL (kill -9) — это уже когда терпения ебать ноль, и этот мудак-процесс вообще не реагирует. Тогда уже — в топку его, без церемоний.