Ответы:
Программа фактически никогда не получает сигнал SIGKILL, поскольку SIGKILL полностью обрабатывается операционной системой / ядром.
Когда отправляется SIGKILL для определенного процесса, планировщик ядра немедленно прекращает предоставлять этому процессу больше процессорного времени для выполнения кода пользовательского пространства. Если у процесса есть какие-либо потоки, выполняющие код пользовательского пространства на других процессорах / ядрах в то время, когда планировщик принимает это решение, эти потоки также будут остановлены. (В одноядерных системах это было намного проще: если планировщик работал только на одном ядре ЦП в системе, он по определению не запускал процесс одновременно!)
Если процесс / поток выполняет код ядра (например, системный вызов или операцию ввода-вывода, связанную с отображенным в память файлом) во время SIGKILL, он становится немного хитрее: только некоторые системные вызовы прерываются, поэтому Ядро внутренне помечает процесс как находящийся в специальном «умирающем» состоянии, пока системные вызовы или операции ввода-вывода не будут разрешены. Время процессора для их решения будет запланировано как обычно. Прерываемые системные вызовы или операции ввода / вывода проверят, умирает ли вызывающий их процесс в любых подходящих точках остановки, и в этом случае завершатся досрочно. Непрерывные операции будут выполняться до конца и будут проверять состояние «умирания» непосредственно перед возвратом к коду пользовательского пространства.
Как только все внутрипроцессные подпрограммы ядра разрешены, состояние процесса изменяется с «умирающего» на «мертвое», и ядро начинает его очищать, подобно тому, как обычно программа завершается. Как только очистка будет завершена, будет назначен код результата, превышающий 128 (чтобы указать, что процесс был прерван сигналом; подробности см. В этом ответе ), и процесс перейдет в состояние «зомби» , Родитель убитого процесса будет уведомлен с сигналом SIGCHLD.
В результате сам процесс никогда не получит возможности фактически обработать информацию, которую он получил SIGKILL.
Когда процесс находится в состоянии «зомби», это означает, что процесс уже мертв, но его родительский процесс еще не подтвердил это, прочитав код завершения мертвого процесса с помощью wait(2)
системного вызова. По сути, единственный ресурс, который зомби-процесс потребляет больше - это слот в таблице процессов, в котором хранятся его PID, код выхода и некоторая другая «важная статистика» процесса в момент его смерти.
Если родительский процесс умирает раньше своих потомков, осиротевшие дочерние процессы автоматически принимаются PID # 1, у которого есть особая обязанность продолжать вызывать вызовы, wait(2)
чтобы любые осиротевшие процессы не оставались зомби.
Если процесс очистки зомби занимает несколько минут, это говорит о том, что родительский процесс зомби испытывает трудности или не выполняет свою работу должным образом.
Существует насмешливое описание того, что делать в случае проблем с зомби в Unix-подобных операционных системах: «Вы ничего не можете сделать для самих зомби, так как они уже мертвы. Вместо этого убейте злого мастера зомби! » (т.е. родительский процесс проблемных зомби)
ps
: 'S' - это ожидания ввода-вывода, которые ядро может отменить для доставки сигнала, и 'D' для тех, которые не могут.