Câu trả lời của @hvd về cơ bản là chính xác. Để sao lưu nhiều hơn nữa, inittrước tiên quy trình sẽ gửi SIGTERMđến các quy trình khi bạn tắt máy tính, sau đó sẽ trì hoãn SIGKILLnếu chúng chưa thoát. Các quy trình không thể xử lý / bỏ qua SIGKILL.
Để cung cấp thêm một chút chi tiết, câu trả lời thực sự là bạn không có cách nào để biết chắc chắn rằng chương trình xử lý nó. SIGTERMlà tín hiệu thông thường nhất được sử dụng để yêu cầu chương trình thoát một cách lịch sự, nhưng tất cả việc xử lý tín hiệu phụ thuộc vào chương trình thực hiện điều gì đó với tín hiệu.
Nói cách khác, dựa trên các câu trả lời khác, nếu bạn có chương trình được viết bởi @Jos hoặc @AlexGreg thì có lẽ họ sẽ xử lý SIGQUITnhưng có thể không SIGTERM, và do đó việc gửi SIGTERMsẽ ít "mềm" hơn SIGQUIT.
Tôi đã viết một số mã để bạn có thể tự chơi xung quanh nó. Lưu dưới đây signal-test.c, sau đó biên dịch với
gcc -o signal-test signal-test.c
Sau đó, bạn có thể chạy nó ./signal-testvà xem điều gì sẽ xảy ra khi bạn gửi các tín hiệu khác nhau 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;
}
Khi nó đứng, mã xử lý cả SIGTERM và SIGQUIT một cách duyên dáng. Bạn có thể thử nhận xét các dòng signal(SIG...(sử dụng a //ở đầu dòng) để loại bỏ trình xử lý tín hiệu, sau đó chạy và gửi lại các tín hiệu. Bạn sẽ có thể thấy các đầu ra khác nhau:
$ ./signal-test
Terminated
$ ./signal-test
Quit (core dumped)
$ ./signal-test
flag is 15
$ ./signal-test
flag is 3
tùy thuộc vào việc bạn xử lý các tín hiệu hay không.
Bạn cũng có thể thử bỏ qua các tín hiệu:
signal(SIGTERM, SIG_IGN);
Nếu bạn làm điều đó thì việc gửi SIGTERMsẽ không làm gì cả, bạn sẽ phải sử dụng SIGKILLđể kết thúc quá trình.
Thêm chi tiết trong man 7 signal. Lưu ý rằng sử dụng signal()theo cách này được coi là không di động - mặc dù vậy nó dễ dàng hơn nhiều so với giải pháp thay thế!
Một chú thích nhỏ khác - về Solaris killallcố gắng giết tất cả các quy trình. Tất cả bọn họ. Nếu bạn chạy nó với quyền root thì bạn có thể ngạc nhiên :)