Ответ @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()таким способом считается непереносимым - это намного проще, чем альтернатива!
Еще одна второстепенная сноска - на Солярисе killallделается попытка уничтожить все процессы. Все они. Если вы запустите его как root, вы можете быть удивлены :)