Як я закінчую всі процеси з тим самим іменем більш щадним чином, ніж killallце? Я не хочу переривати процеси, але залишаю їм час для належного виходу.
Дивись також:
У системному моніторі, яка різниця між Kill Process і End Process?
Як я закінчую всі процеси з тим самим іменем більш щадним чином, ніж killallце? Я не хочу переривати процеси, але залишаю їм час для належного виходу.
Дивись також:
У системному моніторі, яка різниця між Kill Process і End Process?
Відповіді:
killallза замовчуванням надсилає SIGTERM. Це вже приємний підхід, який залишає додаткам можливість прибирати після себе. "Помри вже, прямо зараз!" Підхід полягає в тому, щоб надіслати SIGKILLсигнал, який вимагає вказати це як варіант для killall. З бібліотеки GNU C: сигнали про припинення :
Макрос: int SIGTERM
[...] Це нормальний спосіб ввічливо попросити програму припинити.
Ви посилаєтесь на питання про монітор системи GNOME. Це також використовує SIGTERMдля своєї дії "Кінцевий процес" (і я розумію, що я суперечу відповіді на це питання). Ви можете знайти його у вихідному коді, щоб підтвердити себе:
<item>
<attribute name="label" translatable="yes">_End</attribute>
<attribute name="action">win.send-signal-end</attribute>
<attribute name="accel"><Primary>e</attribute>
<attribute name="target" type="i">15</attribute>
</item>
15 тут - номер сигналу. Сигнал 15 є SIGTERM. І System Monitor використовував SIGTERMзадовго до того, як було задано та відповіли на інше питання.
Ознайомившись із представленням Github git blame, ось такі зміни, які були внесені до того, як сигнали прописані у вихідному коді GNOME System Monitor:
383007f2 24 липня 2013 Замінений дублюючий код для надсилання сигналів з параметрами
GAction 0e766b2d 18 липня 2013 Спливаюче меню порту процесу на GAction
97674c79 3 жовтня 2012 Позбавтеся від структури
ProcData 38c5296c 3 липня 2011 Зробіть відступ рівномірним у вихідних файлах.
Жодне з них не змінилося з SIGQUITна SIGTERM, і останнє було з того, як було задано пов'язане питання.
15? Він може бути змінений в якийсь момент, щоб стара відповідь могла бути на 100% правильною щодо старої версії.
git grep 'SIGQUIT'нічого не виявляє. Нічого, пов'язаного із сигналами, не знайдено для git grep '>3<'жодного. Я роблю висновок, що, швидше за все, gnome-монітор-система ніколи не використовувався SIGQUIT.
git grepшукає лише поточне дерево, а не всю історію. Я використовував git blame(фактично еквівалент Github), щоб копати трохи глибше, але все одно нічого.
Відповідь @hvd в основному правильна. Щоб зробити резервне копіювання ще більше, initпроцес спочатку надсилатиметься SIGTERMдо процесів, коли ви вимикаєте комп'ютер, а потім після затримки надсилатиметься, SIGKILLякщо вони ще не вийшли. Процеси не можуть впоратися / ігноруватиSIGKILL .
Щоб дати трохи більше деталей, справжня відповідь полягає в тому, що ви не можете точно знати, що програма обробляє це. SIGTERMце найбільш звичайний сигнал, який використовується для ввічливого прохання програми вийти, але все обробка сигналу залежить від того, яка програма щось робить із сигналом.
По-іншому, виходячи з інших відповідей, якби у вас була програма, написана @Jos або @AlexGreg, вони, ймовірно, будуть обробляти, SIGQUITале, можливо, ні SIGTERM, і, отже, надсилатиSIGTERM буде менш "м'якою", ніжSIGQUIT .
Я написав якийсь код, щоб ви могли самі пограти з ним. Збережіть нижче як signal-test.c, а потім компілюйте з
gcc -o signal-test signal-test.c
Потім ви можете запустити його ./signal-testі подивитися, що відбувається, коли ви надсилаєте різні сигнали killall -s <signal>.
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
int flag = 0;
void handle_signal(int s)
{
flag = s;
}
int main(int argc, char *argv[])
{
signal(SIGTERM, handle_signal);
signal(SIGQUIT, handle_signal);
while(flag == 0){
sleep(1);
}
printf("flag is %d\n", flag);
return flag;
}
На сьогоднішній день код обробляє SIGTERM і SIGQUIT витончено. Ви можете спробувати коментувати лінії signal(SIG...(використовуючи a //на початку рядка), щоб видалити обробник сигналу, після чого запустіть і надішліть сигнали знову. Ви повинні мати можливість бачити ці різні результати:
$ ./signal-test
Terminated
$ ./signal-test
Quit (core dumped)
$ ./signal-test
flag is 15
$ ./signal-test
flag is 3
залежно від того, обробляєте ви сигнали чи ні.
Ви також можете спробувати ігнорувати сигнали:
signal(SIGTERM, SIG_IGN);
Якщо ви зробите це, то надсилання SIGTERMнічого не призведе, вам доведеться використовувати SIGKILLдля завершення процесу.
Детальніше в man 7 signal. Зауважте, що використання signal()цього способу вважається непортативним - це набагато простіше, ніж альтернатива!
Ще одна незначна виноска - Solaris killallнамагається вбити всі процеси. Усі. Якщо ви запускаєте його як root, то ви можете бути здивовані :)
pkill. Інша причина полягає в тому, що він поєднується з тим pgrep, що полегшує перевірку, які саме процеси будуть вбиті, і які самі семантики краще відповідають, ніж ps | grep.
"Кінець усім" був би killall -s SIGQUIT [process name]. Якщо ви хочете фантазійне рішення, визначтеся alias endall='killall -s SIGQUIT'.
SIGQUITце як зробити процес abort(3): він скидає ядро, а потім вбиває процес. Це ні в якому разі не приємніше / ніжніше / добріше, ніж SIGTERMдля дефолту killall.
SIGQUIT(або ще краще SIGINT), можна поводитись «м'якше», ніж це SIGTERM, але це залежить від програми. Неопрацьований будь-який з них спричиняє негайне припинення.