POSIX(Portable Operating System Interface )信號處理

信號

信號(signal)就是可知某個進程發生了某個事件的通知,有時也稱爲軟件中斷(software interruption)。
信號通常是異步發生的。
信號可以:
*由一個進程發給另一個進程(或自身)
*由內核發給某個進程
每個信號都有一個與之關聯的處置(disposition),也稱爲行爲(action)。
通過sigaction函數來設定一個信號的處置,有三種選擇:
(1)信號發生時調用信號處理函數(signal handler),即捕獲(catching)信號,
其中,SIGKILL,SIGSTOP兩個信號無法被捕捉。
函數原型:void handler(int signo);
(2)通過設置信號處理辦法爲SIG_ING來忽略信號,
其中,SIGKILL,SIGSTOP無法被忽略。
(3)通過設置信號處理辦法爲SIG_DFL來設置信號的默認處置方法,
默認處置通常是早收到信號後終止進程,個別信號的默認處置是忽略。

signal函數

建立信號處置的POSIX方法就是調用sigaction函數。簡單的方法是用signal函數,它的第一個參數是信號名,第二個參數是指向函數的指針或爲常值SIG_DFL或SIG_IGN。
由於歷史原因,signal在各種平臺上的實現可能會不盡相同,而POSIX明確規定調用sigaction函數的語義,但sigaction函數調用往往比較複雜,解決方法是用sigaction實現自己的signal函數,signal函數原型:
void (*signal(int signo, void (*handle)(int)))(int);
其中signal接受兩個參數,一個int型的信號編碼,另一個處理信號的函數指針,然後返回一個之前定義的處理信號的函數的指針,處理函數接受一個int型參數,返回void,這樣看起來挺麻煩的,簡單點可以這樣定義:
typdef void (SIG_HANDLE)(int);
SIG_HANDLE signal(int, SIG_HANDLE );
好了,知道了signal的基本語義了,現在可以用sigaction實現它了,代碼如下:

#include <signal.h>   

/*  
* 用sigaction實現signal  
*/  

typedef void (SIG_PROC)(int);   

SIG_PROC *_signal(int signo, SIG_PROC *sig_proc)   
{   
struct sigaction act;   
struct sigaction oact;   

act.sa_handler = sig_proc;   
// 設置信號處理函數的信號掩碼:信號處理函數調用期間,除屏蔽本信號外,不阻塞其他信號,   
// 信號處理函數執行完畢後,信號屏蔽字恢復到之前的值   
sigemptyset(&act.sa_mask);   
act.sa_flags = 0;   

// 除了SIGALRM以外的其他信號,如果被中斷都將嘗試重新啓動(linux下)   
if (signo == SIGALRM)   
{  
#ifdef SA_INTERRUPT  
act.sa_flags |= SA_INTERRUPT;  
#endif   
}   
else  
{  
#ifdef SA_RESTART   
//如果設置了restart,內核將重啓被中斷的系統調用,系統調用不會返回-1   
act.sa_flags |= SA_RESTART;  
#endif   
}   

if (sigaction(signo, &act, &oact) < 0)   
{   
return SIG_ERR;   
}   
return oact.sa_handler;   
}  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章