Що робить програма, коли вона надсилає сигнал SIGKILL?


39

Коли я killall -9 nameвбивав програму, держава стає зомбі. Через кілька хвилин воно справді зупинилося. Отже, що відбувається за ці хвилини?

Відповіді:


66

Програма насправді ніколи не отримує сигнал SIGKILL, оскільки SIGKILL повністю обробляється операційною системою / ядром.

Коли SIGKILL для певного процесу надсилається, планувальник ядра негайно припиняє давати цьому процесу більше часу для процесора для запуску коду простору користувача. Якщо у процесі є будь-які потоки, що виконують код простору користувача на інших процесорах / ядрах під час прийняття планувальником цього рішення, ці потоки також будуть зупинені. (У одноядерних системах це було набагато простіше: якщо єдине ядро ​​CPU в системі працювало з планувальником, воно за визначенням не запускало процес одночасно!)

Якщо процес / потік виконує код ядра (наприклад, системний виклик або операція вводу / виводу, пов'язана з файлом, нанесеним на пам'ять) під час SIGKILL, він стає трохи складнішим: лише деякі системні виклики перериваються, тому ядро внутрішньо позначає процес як такий, що перебуває у спеціальному "відмираючому" стані, доки системні виклики або операції вводу / виводу не будуть вирішені. Час процесора для їх вирішення буде заплановано як завжди. Переривчасті системні виклики або операції вводу / виводу перевірять, чи не вмирає процес, який їх викликав, у будь-яких відповідних точках зупинки, і вийде рано в цьому випадку. Операції безперебійного виконання завершаться, і перевірять стан "вмираючого" безпосередньо перед поверненням до коду простору користувача.

Після того, як будь-які підпрограми ядра в процесі вирішуються, стан процесу змінюється з "вмираючого" на "мертве", і ядро ​​починає його очищення, подібно до того, коли програма закінчується нормально. Після завершення очищення буде призначено код, що перевищує 128, (щоб вказати, що процес був убитий сигналом; див. Цю відповідь для брудних деталей ), і процес перейде в стан "зомбі" . Батько вбитого процесу буде повідомлений сигналом SIGCHLD.

Як результат, сам процес ніколи не отримає шанс реально обробити інформацію, яку він отримав SIGKILL.

Коли процес перебуває у стані "зомбі", це означає, що процес уже мертвий, але його батьківський процес ще не визнав цього, читаючи вихідний код мертвого процесу за допомогою wait(2)системного виклику. По суті, єдиний ресурс, який витрачає процес зомбі, - це слот в таблиці процесів, який містить його PID, вихідний код та деякі інші "життєві статистичні дані" процесу на момент його загибелі.

Якщо батьківський процес помирає перед його дітьми, діти-сироти автоматично приймаються PID №1, який має особливий обов'язок постійно телефонувати, wait(2)щоб будь-які осиротілі процеси не залишалися навколо зомбі.

Якщо процес очищення зомбі потребує декількох хвилин, це говорить про те, що батьківський процес зомбі бореться або не виконує свою роботу належним чином.

Є чіткий опис того, що робити у випадку проблем із зомбі в Unix-подібних операційних системах: "Ви не можете нічого зробити для самих зомбі, оскільки вони вже мертві. Натомість вбийте злого майстра зомбі! " (тобто батьківський процес проблемних зомбі)


5
Що станеться, якщо процес відбувається під час виклику ядра (наприклад, виконання вводу-виводу), коли SIGKILL надсилається?
gidds

9
@gidds Або введення / вивід буде скасовано для виконання SIGKILL, або SIGKILL буде відкладено до завершення вводу / виводу. Це різниця між станами сну 'S' і 'D' у ps: 'S' - це те, що введення / виведення очікує, що ядро ​​може скасувати, щоб подати сигнал, і 'D' для тих, кого воно не може.
zwol

6
Не зовсім точно сказати, що графік негайно припиняє приділяти процесорові час. Сторона ядра обробки сигналу все ще виконується цим процесом, але процес буде виконувати лише код ядра, тому ви маєте рацію, коли кажете, що програма ніколи не отримує сигнал. Процес буде виконувати код ядра, відповідальний за більшу частину очищення ресурсів (відкриті файли, віртуальна пам'ять тощо). Останніми кроками цього коду очищення є зміна стану процесу на зомбі та виклик планувальника. Тоді це більше ніколи не планується.
kasperd

4
@gidds Існує щонайменше чотири різних стани, в яких може бути процес. Це може бути запущений код ядра на даний момент або він може спати в одному з трьох різних станів сну. Стани сну можуть бути або переривчастими, неперервними, або непереривними, за винятком смертельних сигналів. Якщо він перебуває у безперервному сні, він залишатиметься спати стільки, скільки йому потрібно, і лише раз, коли він прокинеться, у нього буде шанс померти. Якщо він був у одному з двох інших режимів сну, він буде пробуджений негайно і запланований, як тільки для цього буде доступний процесор.
kasperd

2
@gidds Що далі буде залежати від коду ядра, який він виконував. Незалежно від того, він вже запущений або спочатку його потрібно було прокинути, а потім можна почати запускати код ядра, в якому він знаходився в той час, буде дозволено продовжувати. І цей код ядра несе відповідальність за те, щоб помітити, що в процесі було сказано померти і діяти відповідно. Більшість випадків правильним способом впоратися з цим у коді ядра є лише повернення помилки з будь-якої функції, яку вона виконувала. Після того, як стек виклику ядра був розкручений, код обробки сигналу може перейти безпосередньо перед поверненням у режим користувача.
kasperd
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.