Коли я killall -9 name
вбивав програму, держава стає зомбі. Через кілька хвилин воно справді зупинилося. Отже, що відбувається за ці хвилини?
Коли я killall -9 name
вбивав програму, держава стає зомбі. Через кілька хвилин воно справді зупинилося. Отже, що відбувається за ці хвилини?
Відповіді:
Програма насправді ніколи не отримує сигнал SIGKILL, оскільки SIGKILL повністю обробляється операційною системою / ядром.
Коли SIGKILL для певного процесу надсилається, планувальник ядра негайно припиняє давати цьому процесу більше часу для процесора для запуску коду простору користувача. Якщо у процесі є будь-які потоки, що виконують код простору користувача на інших процесорах / ядрах під час прийняття планувальником цього рішення, ці потоки також будуть зупинені. (У одноядерних системах це було набагато простіше: якщо єдине ядро CPU в системі працювало з планувальником, воно за визначенням не запускало процес одночасно!)
Якщо процес / потік виконує код ядра (наприклад, системний виклик або операція вводу / виводу, пов'язана з файлом, нанесеним на пам'ять) під час SIGKILL, він стає трохи складнішим: лише деякі системні виклики перериваються, тому ядро внутрішньо позначає процес як такий, що перебуває у спеціальному "відмираючому" стані, доки системні виклики або операції вводу / виводу не будуть вирішені. Час процесора для їх вирішення буде заплановано як завжди. Переривчасті системні виклики або операції вводу / виводу перевірять, чи не вмирає процес, який їх викликав, у будь-яких відповідних точках зупинки, і вийде рано в цьому випадку. Операції безперебійного виконання завершаться, і перевірять стан "вмираючого" безпосередньо перед поверненням до коду простору користувача.
Після того, як будь-які підпрограми ядра в процесі вирішуються, стан процесу змінюється з "вмираючого" на "мертве", і ядро починає його очищення, подібно до того, коли програма закінчується нормально. Після завершення очищення буде призначено код, що перевищує 128, (щоб вказати, що процес був убитий сигналом; див. Цю відповідь для брудних деталей ), і процес перейде в стан "зомбі" . Батько вбитого процесу буде повідомлений сигналом SIGCHLD.
Як результат, сам процес ніколи не отримає шанс реально обробити інформацію, яку він отримав SIGKILL.
Коли процес перебуває у стані "зомбі", це означає, що процес уже мертвий, але його батьківський процес ще не визнав цього, читаючи вихідний код мертвого процесу за допомогою wait(2)
системного виклику. По суті, єдиний ресурс, який витрачає процес зомбі, - це слот в таблиці процесів, який містить його PID, вихідний код та деякі інші "життєві статистичні дані" процесу на момент його загибелі.
Якщо батьківський процес помирає перед його дітьми, діти-сироти автоматично приймаються PID №1, який має особливий обов'язок постійно телефонувати, wait(2)
щоб будь-які осиротілі процеси не залишалися навколо зомбі.
Якщо процес очищення зомбі потребує декількох хвилин, це говорить про те, що батьківський процес зомбі бореться або не виконує свою роботу належним чином.
Є чіткий опис того, що робити у випадку проблем із зомбі в Unix-подібних операційних системах: "Ви не можете нічого зробити для самих зомбі, оскільки вони вже мертві. Натомість вбийте злого майстра зомбі! " (тобто батьківський процес проблемних зомбі)
ps
: 'S' - це те, що введення / виведення очікує, що ядро може скасувати, щоб подати сигнал, і 'D' для тих, кого воно не може.