signal訊號相關資料
https://blog.csdn.net/fz_ywj/article/details/9124401
SIGQUIT、SIGTERM、SIGINT、SIGKILL區別:
1. SIGQUIT:
在POSIX相容的平臺,SIGQUIT是其控制終端傳送到程序,當用戶請求的過程中執行核心轉儲的訊號。 SIGQUIT通常可以ctrl+ \。在Linux上,人們還可以使用Ctrl-4或虛擬控制檯,SysRq yek。
2. SIGTERM:
SIGTERM是殺或的killall命令傳送到程序預設的訊號。它會導致一過程的終止,但是SIGKILL訊號不同,它可以被捕獲和解釋(或忽略)的過程。因此,SIGTERM類似於問一個程序終止可好,讓清理檔案和關閉。因為這個原因,許多Unix系統關機期間,初始化問題SIGTERM到所有非必要的斷電過程中,等待幾秒鐘,然後發出SIGKILL強行終止仍然存在任何這樣的過程。
3. SIGINT:
符合POSIX平臺,訊號情報是由它的控制終端,當用戶希望中斷該過程傳送到處理的訊號。通常ctrl-C,但在某些系統上,“刪除”字元或“break”鍵 - 當程序的控制終端的使用者按下中斷正在執行的程序的關鍵SIGINT被髮送。
4. SIGKILL:
上符合POSIX平臺上,SIGKILL是傳送到處理的訊號以使其立即終止。當傳送到程式,SIGKILL使其立即終止。在對比SIGTERM和SIGINT,這個訊號不能被捕獲或忽略,並且在接收過程中不能執行任何清理在接收到該訊號。
檢視Linux signal 訊號定義,一共64個.
kill -l
The first 31 signals in Linux/i386 |
||||
# |
Signal name |
Default action |
Comment |
POSIX |
1 |
SIGHUP |
Terminate |
Hang up controlling terminal or process |
Yes |
2 |
SIGINT |
Terminate |
Interrupt from keyboard |
Yes |
3 |
SIGQUIT |
Dump |
Quit from keyboard |
Yes |
4 |
SIGILL |
Dump |
Illegal instruction |
Yes |
5 |
SIGTRAP |
Dump |
Breakpoint for debugging |
No |
6 |
SIGABRT |
Dump |
Abnormal termination |
Yes |
6 |
SIGIOT |
Dump |
Equivalent to SIGABRT |
No |
7 |
SIGBUS |
Dump |
Bus error |
No |
8 |
SIGFPE |
Dump |
Floating-point exception |
Yes |
9 |
SIGKILL |
Terminate |
Forced-process termination |
Yes |
10 |
SIGUSR1 |
Terminate |
Available to processes |
Yes |
11 |
SIGSEGV |
Dump |
Invalid memory reference |
Yes |
12 |
SIGUSR2 |
Terminate |
Available to processes |
Yes |
13 |
SIGPIPE |
Terminate |
Write to pipe with no readers |
Yes |
14 |
SIGALRM |
Terminate |
Real-timerclock |
Yes |
15 |
SIGTERM |
Terminate |
Process termination |
Yes |
16 |
SIGSTKFLT |
Terminate |
Coprocessor stack error |
No |
17 |
SIGCHLD |
Ignore |
Child process stopped or terminated, or got signal if traced |
Yes |
18 |
SIGCONT |
Continue |
Resume execution, if stopped |
Yes |
19 |
SIGSTOP |
Stop |
Stop process execution |
Yes |
20 |
SIGTSTP |
Stop |
Stop process issued from tty |
Yes |
21 |
SIGTTIN |
Stop |
Background process requires input |
Yes |
22 |
SIGTTOU |
Stop |
Background process requires output |
Yes |
23 |
SIGURG |
Ignore |
Urgent condition on socket |
No |
24 |
SIGXCPU |
Dump |
CPU time limit exceeded |
No |
25 |
SIGXFSZ |
Dump |
File size limit exceeded |
No |
26 |
SIGVTALRM |
Terminate |
Virtual timer clock |
No |
27 |
SIGPROF |
Terminate |
Profile timer clock |
No |
28 |
SIGWINCH |
Ignore |
Window resizing |
No |
29 |
SIGIO |
Terminate |
I/O now possible |
No |
29 |
SIGPOLL |
Terminate |
Equivalent to SIGIO |
No |
30 |
SIGPWR |
Terminate |
Power supply failure |
No |
31 |
SIGSYS |
Dump |
Bad system call |
No |
31 |
SIGUNUSED |
Dump |
Equivalent to SIGSYS |
No |
signal 使用教程。
訊號分成兩種:
regular signal(非實時訊號),對應的編碼值為[1,31]
real time signal對應的編碼值為[32,64]
編碼為0的訊號不是有效訊號,只用於檢查是當前程序否有傳送訊號的許可權,並不真正傳送。
執行緒會有自己的懸掛訊號佇列, 並且執行緒組也有一個訊號懸掛佇列.
訊號懸掛佇列儲存task例項接收到的訊號,只有當該訊號被處理後它才會從懸掛佇列中卸下.
訊號懸掛佇列還有一個對應的阻塞訊號集合,當一個訊號在阻塞訊號集合中時,task不會處理該被阻塞的訊號(但是該訊號依舊在懸掛佇列中). 當阻塞取消時,它會被處理.
對一個訊號,要三種處理方式:
1.忽略該訊號(Ignore);//對應SIG_IGN
2.採用預設方式處理(呼叫系統指定的訊號處理函式,default);//對應SIG_DFL
3.使用使用者指定的方式處理(呼叫使用者指定的訊號處理函式).
signal()函式詳解 void (*signal (int sig ,void (*func)(int))) (int) ;
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
signal函式
作用1:站在應用程式的角度,註冊一個訊號處理函式
作用2:忽略訊號,設定訊號預設處理 訊號的安裝和回覆
引數
--signal是一個帶signum和handler兩個引數的函式.
準備捕捉或遮蔽的訊號由引數signum給出,通過kill -l檢視一共64個。
接收到指定訊號時將要呼叫的函式有handler給出
--handler這個函式必須有一個int型別的引數(即接收到的訊號程式碼),它本身的型別是void
--handler也可以是下面兩個特殊值:
① SIG_IGN 遮蔽該訊號
② SIG_DFL 恢復預設行為
1.SIG_IGN
#include <stdio.h>
#include <signal.h>
int main(int argc , char *argv[])
{
signal(SIGINT,SIG_IGN);
for(;;);
return 0;
}
gcc 命令編譯後執行,按下ctrl+C有沒有發現無法終止程式?
網上有人說用Ctrl+\來終止,我的系統是CentOS7,ctrl+\無效,倒是Ctrl+z可終止程式。
2.SIG_DFL
#include <stdio.h>
#include <signal.h>
int main(int argc , char *argv[])
{
// signal(SIGINT,SIG_DFL);//此語句註釋還是不註釋,其結果都是一樣的,系統預設Ctrl+C可終止。
for(;;);
return 0;
}
3.自定義訊號處理方式
#include <stdio.h>
#include <signal.h>
typedef void(*signal_handler)(int);
void signal_handler_fun(int signal_num)
{
printf("signal num is %d\n",signal_num); //按下ctrl+C中斷後,該值為2,其實就是SIGINT,kill -l可檢視到。
}
int main(int argc,char * argv[])
{
signal_handler p_signal = signal_handler_fun;
signal(SIGINT,p_signal);
for(;;);
return 0;
}
gcc編譯執行科檢視結果,Ctrl+C組合鍵按下輸出2,Ctrl+Z退出程式。
檢視連結:https://blog.csdn.net/chenjianqi0502/article/details/78579541