1. 程式人生 > >c語言中signal函式詳細解釋說明

c語言中signal函式詳細解釋說明

對於 訊號處理函式 位於 <signal.h> 中.
void ( *signal( int sig, void (* handler)( int ))) ( int );
這個函式的宣告很是嚇人, 一看就難弄懂. 下面是解釋用法.
一步一步解釋:
int (*p)();
這是一個函式指標, p所指向的函式是一個不帶任何引數, 並且返回值為int的一個函式.
int (*fun())();
這個式子與上面式子的區別在於用fun()代替了p,而fun()是一個函式,所以說就可以看成是fun()這個函式執行之後,它的返回值是一個函式指標,這個函式指標(其實就是上面的p)所指向的函式是一個不帶任何引數,並且返回值為int的一個函式. 所以說對於void (*signal(int signo, void (*handler)(int)))(int);就可以看成是signal()函式(它自己是帶兩個引數,一個為整型,一個為函式指標的函式), 而這個signal()函式的返回值也為一個函式指標,這個函式指標指向一個帶一個整型引數,並且返回值為void的一個函式.

而你在寫訊號處理函式時對於訊號處理的函式也是void sig_fun(int signo);這種型別,恰好與上面signal()函式所返回的函式指標所指向的函式是一樣的.
注意, void ( *signal() )( int ); signal是一個函式, 它返回一個函式指標, 後者所指向的函式接受一個整型引數 且沒有返回值, 仔細看, 是不是siganal( int signo, void (*handler)(int) )的第2個引數了, 對了, 其實他所返回的就是 signal的第2個訊號處理函式, 指向訊號處理函式, 就可以執行函數了( signal內部時, signal把訊號做為引數傳遞給handler訊號處理函式, 接著 signal 函式返回指標, 並且又指向訊號處理函式, 就開始執行它)
對於這個問題, 在<C陷阱與缺陷>這本書中講得很清晰, 可以看一看.
 
在signal.h標頭檔案中還有以下幾個定義
#define SIG_ERR (void (*)())-1
#define SIG_DFL (void (*)())0
#define SIG_IGN (void (*)())1
 
系統呼叫signal用來設定某個訊號的處理方法。該呼叫宣告的格式如下:
void (*signal(int signum, void (*handler)(int)))(int);
在使用該呼叫的程序中加入以下標頭檔案:
#include <signal.h> 上述宣告格式比較複雜,如果不清楚如何使用,也可以通過下面這種型別定義的格式來使用(POSIX的定義):
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
但這種格式在不同的系統中有不同的型別定義,所以要使用這種格式,最好還是參考一下聯機手冊。 在呼叫中,引數signum指出要設定處理方法的訊號。第二個引數handler是一個處理函式,或者是
SIG_IGN:忽略引數signum所指的訊號。
SIG_DFL:恢復引數signum所指訊號的處理方法為預設值。 傳遞給訊號處理例程的整數引數是訊號值,這樣可以使得一個訊號處理例程處理多個訊號。系統呼叫signal返回值是指定訊號signum前一次的處理例程或者錯誤時返回錯誤程式碼SIG_ERR。下面來看一個簡單的例子: #include <signal.h>
#include <unistd.h>
#include <stdio.h>
void sigroutine(int dunno) { /* 訊號處理例程,其中dunno將會得到訊號的值 */
switch (dunno) {
case 1:
printf("Get a signal -- SIGHUP ");
break;
case 2:
printf("Get a signal -- SIGINT ");
break;
case 3:
printf("Get a signal -- SIGQUIT ");
break;
}
return;
} int main() {
printf("process id is %d ",getpid());
signal(SIGHUP, sigroutine); //* 下面設定三個訊號的處理方法
signal(SIGINT, sigroutine);
signal(SIGQUIT, sigroutine);
for (;;) ;
} 其中訊號SIGINT由按下Ctrl-C發出,訊號SIGQUIT由按下Ctrl-發出。該程式執行的結果如下: localhost:~$ ./sig_test
process id is 463
Get a signal -SIGINT //按下Ctrl-C得到的結果
Get a signal -SIGQUIT //按下Ctrl-得到的結果
//按下Ctrl-z將程序置於後臺
[1]+ Stopped ./sig_test
localhost:~$ bg
[1]+ ./sig_test &
localhost:~$ kill -HUP 463 //向程序傳送SIGHUP訊號
localhost:~$ Get a signal – SIGHUP
kill -9 463 //向程序傳送SIGKILL訊號,終止程序
localhost:~$