1. 程式人生 > >linux下的訊號機制(signel)--持續更新中

linux下的訊號機制(signel)--持續更新中

1、訊號的基本概念

        程序之間可以互相通過系統呼叫kill傳送軟中斷訊號。核心也可以因為內部事件而給程序傳送訊號,通知程序發生了某個事件。程序通過系統呼叫signal來指定程序對某個訊號的處理行為。

2、訊號本質是int型數字編號(事先定義好的)

        解釋:訊號只是用來通知某程序發生了什麼事件,並不給該程序傳遞任何資料(比如文字,語音等資料),他是核心事先定義好的int數字,呼叫signal函式時,來指定訊號內型。

3、誰發出的訊號

        (1)使用者在ubuntu終端(終端就是一個前臺執行的程序)按下按鍵比如ctrl+C等

        (2)硬體異常後,作業系統核心傳送訊號

        (3)使用者使用kill命令(是一個核心提供的API函式)比如用:kill  - 9  xxx

        (4)某種軟體條件滿足後也會發送訊號,如alarm鬧鐘時間到會產生SIGALARM訊號、向一個讀端已近關閉的管道write時,會產生SIGPIPE

4、訊號由誰處理,處理方式

 (1)捕獲訊號,程序可以指定處理函式,由該函式來處理。

        (2)忽略訊號,對該訊號不做任何處理,就象未發生過一樣。

        (3)預設處理,這種預設操作,對大部分的訊號的預設操作是使得程序終止。

5、每個int型的訊號值發生的原因(這裡列出常見的幾種)

    5.1在linux下/usr/include/i386-linux-gnu/bits 下的signum.h定義了所以的訊號值

訊號 值 處理動作 發出訊號的原因

         SIGHUP 1 A 終端掛起或者控制程序終止 
SIGINT 2 A 鍵盤中斷(如break鍵被按下) 正常終止
         SIGQUIT 3 C 鍵盤的退出鍵被按下 
         SIGILL 4 C 非法指令 


 SIGABRT 6 C 由abort(3)發出的退出指令,異常終止
SIGIO 23,29,22 A 某I/O操作現在可以進行了(4.2 BSD)
SIGKILL 9 AEF 殺死程序的終極方法
SIGSEGV 11 C 無效的記憶體引用 
SIGPIPE 13 A 管道破裂: 寫一個沒有讀埠的管道 
SIGALRM 14 A 由alarm(2)發出的訊號 
SIGTERM 15 A 終止訊號 
SIGUSR1 30,10,16 A 使用者自定義訊號1 給使用者做程序間通訊,不像其他的處理方法被綁定了
SIGUSR2 31,12,17 A 使用者自定義訊號2 
SIGCHLD 20,17,18 B 子程序結束訊號 
         SIGCONT 19,18,25 程序繼續(曾被停止的程序) 
         SIGSTOP 17,19,23 DEF 終止程序 
         SIGTSTP 18,20,24 D 控制終端(tty)上按下停止鍵 
         SIGTTIN 21,21,26 D 後臺程序企圖從控制終端讀 
         SIGTTOU 22,22,27 D 後臺程序企圖從控制終端寫       

    5.2處理動作一項中的字母含義如下 

            A 預設的動作是終止程序 
             B 預設的動作是忽略此訊號 
            C 預設的動作是終止程序並進行核心映像轉儲(dump core) 
            D 預設的動作是停止程序 
            E 訊號不能被捕獲 

             F 訊號不能被忽略

6、程序對訊號的處理例項

    6.1、signal系統呼叫

            (1)宣告如下:      typedef void (*sighandler_t) (int); 
             sighandler_t signal( int signum, sighandler_t handler ); 
         解釋:sighandler_t是一個函式指標,這個函式指標指向的函式接受一個int引數,返回一個void 型別            (2)在呼叫中,引數signum指出要設定處理方法的訊號。第二個引數handler是一個處理函式,或者是                       SIG_INT:捕獲這個訊號,並處理handler函式
                    SIG_IGN:忽略引數signum所指的訊號。 
                    SIG_DFL:恢復引數signum所指訊號的處理方法為預設值。
            (3)細節:

                    一、signal函式繫結一個捕獲函式後訊號發生後會自動執行繫結的捕獲函式,並且把訊號編號作為傳參傳給捕獲函式

                    二、signal的返回值在出錯時為SIG_ERR,繫結成功時返回舊的捕獲函式

    6.2、signal程式碼示例

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>

typedef void (*sighandler_t)(int);     //下面使用核心用sighandler_t定義的SIG_DFL,需要宣告一下

void func(int sig)
{
if (SIGINT != sig)
            return 0;
printf("func for signal: %d.\n", sig);
}
int main(void)
{
sighandler_t ret = (sighandler_t)(-2);    //
//signal(SIGINT, func) ;
//signal(SIGINT, SIG_DFL);// 指定訊號SIGINT為預設處理
ret = signal(SIGINT, SIG_IGN);        // 指定訊號SIGINT為忽略處理
if (SIG_ERR == ret)
{
perror("signal:");
exit(-1);
}

printf("before while(1)\n");
while(1);
printf("after while(1)\n");

return 0;

}