Signal ()函數用法和總結


void(* signal(int sig,void(* func)(int)))(int);
設置處理信號的功能

指定使用sig指定信號編號處理信號的方法 參數func指定程序可以處理信號的三種方式之一:

  • 默認處理(SIG_DFL):信號由該特定信號的默認動作處理。
  • 忽略信號(SIG_IGN):忽略信號,即使沒有意義,代碼執行仍將繼續。
  • 函數處理程序:定義一個特定的函數來處理信號。


或 SIG_DFL 要么 SIG_IGN 被設置為程序啟動時每個支持信號的默認信號處理行為。

參數

SIG
設置處理功能 信號值 以下宏常量表達式標識標准信號值:

信號
SIGABRT (信號中止)異常終止,例如由...發起 退出 功能。
SIGFPE (信號浮點異常)錯誤的算術運算,例如零分頻或導致溢出的運算(不一定是浮點運算)。
SIGILL (信號非法指令)無效的功能圖像,例如非法指令。這通常是由於代碼中的損壞或嘗試執行數據。
SIGINT (信號中斷)交互式注意信號。通常由應用程序用戶生成。
SIGSEGV (信號分段違規)對存儲的無效訪問:當程序試圖在已分配的內存之外讀取或寫入時。
SIGTERM (信號終止)發送到程序的終止請求。

每個庫實現可以提供可以與此函數一起使用的附加 信號值 宏常量。

請注意,並非所有運行環境都需要生成自動信號,即使在上述特定情況下也是如此,盡管所有運行環境都必須通過顯式調用生成的信號來生成 提高  功能。
FUNC
指向函數的指針。這可以是程序員定義的函數,也可以是以下預定義函數之一:

SIG_DFL 默認處理:信號由該特定信號的默認操作處理。
SIG_IGN 忽略信號:忽略信號。

如果是一個函數,它應該遵循以下原型(使用C鏈接):
void handler_function (int parameter);

返回值

返回類型與參數func的類型相同

如果請求成功,則該函數返回指向特定處理函數的指針,該函數在調用之前負責處理該信號(如果有的話)。或者SIG_DFL 要么 SIG_IGN如果在調用之前信號由默認處理程序處理或被忽略,則相應地。

如果該功能未能成功注冊新的信號處理程序,則返回SIG_ERR 和 錯誤號 可以設置為正值。

/* signal example */
#include <stdio.h>      /* printf */
#include <signal.h>     /* signal, raise, sig_atomic_t */

sig_atomic_t signaled = 0;

void my_handler (int param)
{
  signaled = 1;
}

int main ()
{
  void (*prev_handler)(int);

  prev_handler = signal (SIGINT, my_handler);

  /* ... */
  raise(SIGINT);
  /* ... */
  
  printf ("signaled is %d.\n",signaled);
  

  return 0;
}

  

#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);

  第一個參數是要捕捉的信號(查看信號:kill -l,9號SIGKILL信號不能被捕捉); 
第二個參數表示我們要對信號進行的處理方式。 
信號的處理方式一般有三種: 
(1)忽略此信號(SIG_IGN):

#include<stdio.h>
#include<signal.h>
int main()
{
    signal(2,SIG_IGN);
    while(1)
    {
        printf("2333\n");
        sleep(1);
    }
    return 0;
}

  當執行程序時,陷入死循環,此時按下Ctrl+c進程並不會停止,因為我們對Ctrl+c產生的2號SIGINT信號采取了忽略處理,若要停止進程可用Ctrl+z(SIGQUIT); 

運行結果如下:

 

(2)執行該信號的默認處理動作(SIG_DFL):

#include<stdio.h>
#include<signal.h>
int main()
{
    signal(2,SIG_DFL);
    while(1)
    {
        printf("2333\n");
        sleep(1);
    }
    return 0;
}

  當執行程序時,同樣是死循環,此時按下Ctrl+z進程停止,因為我們對2號信號采取默認動作處理,系統默認2號信號終止進程。 
(3提供一個信號處理函數,要求內核在處理該信號時切換到用戶態執行這個處理函數,這種方式稱為捕捉(catch)一個信號:

#include<stdio.h>
#include<signal.h>
void  handler(int signo)//自定義一個函數處理信號
{
    printf("catch a signal:%d\n:",signo);
}
int main()
{
    signal(2,handler);
    while(1)
    {
        printf("1111\n");
        sleep(1);
    }
    return 0;
}

  運行結果如圖: 

 

一些常用的Signal :

Signal  Description
SIGABRT 由調用abort函數產生,進程非正常退出
SIGALRM 用alarm函數設置的timer超時或setitimer函數設置的interval timer超時
SIGBUS 某種特定的硬件異常,通常由內存訪問引起
SIGCANCEL 由Solaris Thread Library內部使用,通常不會使用
SIGCHLD  進程Terminate或Stop的時候,SIGCHLD會發送給它的父進程。缺省情況下該Signal會被忽略
SIGCONT 當被stop的進程恢復運行的時候,自動發送
SIGEMT  和實現相關的硬件異常
SIGFPE 數學相關的異常,如被0除,浮點溢出,等等
SIGFREEZE Solaris專用,Hiberate或者Suspended時候發送
SIGHUP 發送給具有Terminal的Controlling Process,當terminal 被disconnect時候發送
SIGILL 非法指令異常
SIGINFO  BSD 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的時候發送
SIGPROF Setitimer指定的Profiling Interval Timer所產生
SIGPWR 和系統相關。和UPS相關。
SIGQUIT 輸入Quit Key的時候(CTRL+\)發送給所有Foreground Group的進程
SIGSEGV 非法內存訪問
SIGSTKFLT Linux專用,數學協處理器的棧異常
SIGSTOP 中止進程。無法處理和忽略。
SIGSYS 非法系統調用
SIGTERM 請求中止進程,kill命令缺省發送
SIGTHAW Solaris專用,從Suspend恢復時候發送
SIGTRAP 實現相關的硬件異常。一般是調試異常
SIGTSTP Suspend Key,一般是Ctrl+Z。發送給所有Foreground Group的進程
SIGTTIN 當Background Group的進程嘗試讀取Terminal的時候發送
SIGTTOU 當Background Group的進程嘗試寫Terminal的時候發送
SIGURG 當out-of-band data接收的時候可能發送
SIGUSR1  用戶自定義signal 1
SIGUSR2 用戶自定義signal 2
SIGVTALRM setitimer函數設置的Virtual Interval Timer超時的時候
SIGWAITING Solaris Thread Library內部實現專用
SIGWINCH 當Terminal的窗口大小改變的時候,發送給Foreground Group的所有進程
SIGXCPU 當CPU時間限制超時的時候
SIGXFSZ 進程超過文件大小限制
SIGXRES Solaris專用,進程超過資源限制的時候發

 

 

 
 
 
 
 
 
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM