signal

計算機學

sig是傳遞給它的唯一參數。執行了signal()調用后,進程只要接收到類型為sig的信號,不管其正在執行程序的哪一部分,就立即執行func()函數。當func()函數執行結束后,控制權返回進程被中斷的那一點繼續執行。

函數名: signal


表頭文件#include
功 能:設置某一信號的對應動作
函數原型:void (*signal(int signum,void(* handler)(int)))(int);
或者:typedef void (*sig_t)( int );
sig_t signal(int signum,sig_t handler);
參數說明:
第一個參數signum指明了所要處理的信號類型,它可以取除了SIGKILL和SIGSTOP外的任何一種信號。
第二個參數handler描述了與信號關聯的動作,它可以取以下三種值:
(1)一個無返回值的函數地址
此函數必須在signal()被調用前申明,handler中為這個函數的名字。當接收到一個類型為signum的信號時,就執行handler 所指定的函數。這個函數應有如下形式的定義:
void func(int sig);
(2)SIG_IGN
這個符號表示忽略該信號,執行了相應的signal()調用后,進程會忽略類型為sig的信號。
(3)SIG_DFL
這個符號表示恢復系統對信號的默認處理。
函數說明:
signal()會依參數signum 指定的信號編號來設置該信號的處理函數。當指定的信號到達時就會跳轉到參數handler指定的函數執行。當一個信號的信號處理函數執行時,如果進程又接收到了該信號,該信號會自動被儲存而不會中斷信號處理函數的執行,直到信號處理函數執行完畢再重新調用相應的處理函數。但是如果在信號處理函數執行時進程收到了其它類型的信號,該函數的執行就會被中斷。
返回值:返回先前的信號處理函數指針,如果有錯誤則返回SIG_ERR(-1)。
下面的情況可以產生Signal:
1.按下CTRL+C產生SIGINT
2.硬體中斷,如除0,非法內存訪問(SIGSEV)等等
3.Kill函數可以對進程發送Signal
4.Kill命令。實際上是對Kill函數的一個包裝
5.軟體中斷。如當Alarm Clock超時(SIGURG),當Reader中止之後又向管道寫數據(SIGPIPE),等等
程序例:
#pragma inline
#include
#include
void Catcher(int sig, int type, int *reglist)
{
printf("Caught it!\n");
*(reglist + 8) = 3;
}
int main(void)
{
signal(SIGFPE, Catcher);
asm mov ax,07FFFH
asm inc ax
asm into
asm dec ax
asm into
return 0;
}
2 Signals:
SignalDescription
SIGABRT由調用abort函數產生,進程非正常退出
SIGALRM用alarm函數設置的timer超時或setitimer函數設置的interval timer超時
SIGBUS某種特定的硬體異常,通常由內存訪問引起
SIGCANCEL由Solaris Thread Library內部使用,通常不會使用
SIGCHLD進程Terminate或Stop的時候,SIGCHLD會發送給它的父進程。預設情況下該Signal會被忽略
SIGCONT當被stop的進程恢復運行的時候,自動發送
SIGEMT和實現相關的硬體異常
SIGFPE數學相關的異常,如被0除,浮點溢出,等等
SIGFREEZESolaris專用,Hiberate或者Suspended時候發送
SIGHUP發送給具有Terminal的Controlling Process,當terminal被disconnect時候發送
SIGILL非法指令異常
SIGINFOBSD signal。由Status Key產生,通常是CTRL+T。發送給所有Foreground Group的進程
SIGINT由Interrupt Key產生,通常是CTRL+C或者DELETE。發送給所有ForeGround Group的進程
SIGIO非同步IO事件
SIGIOT實現相關的硬體異常,一般對應SIGABRT
SIGKILL無法處理和忽略。中止某個進程
SIGLWP由Solaris Thread Libray內部使用
SIGPIPE在reader中止之後寫Pipe的時候發送
SIGPOLL當某個事件發送給Pollable Device的時候發送
SIGPROFSetitimer指定的Profiling Interval Timer所產生
SIGPWR和系統相關。和UPS相關。
SIGQUIT輸入Quit Key的時候(CTRL+\)發送給所有Foreground Group的進程
SIGSEGV非法內存訪問
SIGSTKFLTLinux專用,數學協處理器的棧異常
SIGSTOP中止進程。無法處理和忽略。
SIGSYS非法系統調用
SIGTERM請求中止進程,kill命令預設發送
SIGTHAWSolaris專用,從Suspend恢復時候發送
SIGTRAP實現相關的硬體異常。一般是調試異常
SIGTSTPSuspend Key,一般是Ctrl+Z。發送給所有Foreground Group的進程
SIGTTIN當Background Group的進程嘗試讀取Terminal的時候發送
SIGTTOU當Background Group的進程嘗試寫Terminal的時候發送
SIGURG當out-of-band data接收的時候可能發送
SIGUSR1用戶自定義signal 1
SIGUSR2用戶自定義signal 2
SIGVTALRMsetitimer函數設置的Virtual Interval Timer超時的時候
SIGWAITINGSolaris Thread Library內部實現專用
SIGWINCH當Terminal的窗口大小改變的時候,發送給Foreground Group的所有進程
SIGXCPU當CPU時間限制超時的時候
SIGXFSZ進程超過文件大小限制
SIGXRESSolaris專用,進程超過資源限制的時候發送

注意點


1、不要使用低級的或者STDIO.H的IO函數
2、不要使用對操作
3、不要進行系統調用
4、不是浮點信號的時候不要用 longjmp
5、signal函數是由ISO C定義的。因為ISO C不涉及多進程,進程組以及終端I/O等,所以他對信號的定義非常含糊,以至於對UNIX系統而言幾乎毫無用處。
備註:因為signal的語義與現實有關,所以最好使用sigaction函數替代本函數。