系統函式之signal 詳解

2021-06-29 15:06:17 字數 3705 閱讀 5322

表頭檔案#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

這個符號表示恢復系統對訊號的預設處理。

#define sig_err (void(*)())-1

#define sig_dfl (void(*)())0

#define sig_ign (void(*)())1

函式說明

signal()會依引數signum 指定的訊號編號來設定該訊號的處理函式。當指定的訊號到達時就會跳轉到引數handler指定的函式執行。當乙個訊號的訊號處理函式執行時,如果程序又接收到了該訊號,該訊號會自動被儲存而不會中斷訊號處理函式的執行,直到訊號處理函式執行完畢再重新呼叫相應的處理函式。但是如果在訊號處理函式執行時程序收到了其它型別的訊號,該函式的執行就會被中斷。

返回值:返回先前的訊號處理函式指標,如果有錯誤則返回sig_err(-1)。

下面的情況可以產生signal:

按下ctrl+c產生sigint

硬體中斷,如除0,非法記憶體訪問(sigsev)等等

kill函式可以對程序傳送signal

kill命令。實際上是對kill函式的乙個包裝

軟體中斷。如當alarm clock超時(sigurg),當reader中止之後又向管道寫資料(sigpipe),等等

問題:瀏覽器與服務端建立連線後,若重新整理或關閉瀏覽器視窗(未監聽相應事件並處理),服務端無法得知連線斷開,按理說,這種情況屬於client異常終止,跟拔網線的情況類似。這種情況下,服務端不知情,仍保留此連線,仍按照既定邏輯向client寫資料,寫了兩次後,服務端程式終止(多次測試,均是第2次後終止),不是崩潰,是異常終止,非常不解。

問了一位很有經驗的同事,得知是sigpipe訊號導致程式終止。

查了相關資料,大致明白:連線建立,若某一端關閉連線,而另一端仍然向它寫資料,第一次寫資料後會收到rst響應,此後再寫資料,核心將向程序發出sigpipe訊號,通知程序此連線已經斷開。而sigpipe訊號的預設處理是終止程式,導致上述問題的發生。

訊號量表:

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專用,程序超過資源限制的時候傳送

訊號之signal函式

unix系統的訊號機制最簡單的介面是signal函式。signal函式的功能 為指定的訊號安裝乙個新的訊號處理函式。include void signal int signo,void func int int 複雜原型分開看 void signal int signo,void func int ...

訊號之signal函式

unix系統的訊號機制最簡單的介面是signal函式。signal函式的功能 為指定的訊號安裝乙個新的訊號處理函式。include void signal int signo,void func int int 複雜原型分開看 void signal int signo,void func int ...

linux下signal 函式詳解

設定某一訊號的對應動作 include typedef void sighandler t int sighandler t signal int signum,sighandler t handler 第乙個引數signum 指明了所要處理的訊號型別,它可以取除了sigkill和sigstop外的...