基本概念
信號是事件發生時對進程的通知機制。有時也稱爲軟件中斷,信號與硬件中斷相似之處在於打斷了程序執行的正常流程,大多數情況下,無法預測信號到達的精確時間。
一個具有合適權限的進程能夠向另一進程發送信號,信號的這一用法可作爲一種同步技術,甚至是進程通信IPC的原始形式。進程也可以向自身發送信號。然而發往進程的諸多信號,通常都是源於內核。
引發內核爲進程產生信號的各類事件如下:
硬件發生異常:硬件異常的例子包括執行一條異常的機器語言指令,如被0除,或者引用了無法訪問的內存區域。
用戶鍵入能夠產生信號的中斷特殊字符:包括中斷字符(Control-C)
發生了軟件事件:列入,針對文件描述符的輸出變爲有效,調整了中斷窗口大小、定時器到期、進程執行的CPU時間超限、或者改進程的某個子進程退出
信號分兩大類:
內核向進程通知事件,構成所謂傳統或者標準信號,編號1~31。
實時信號
信號產生後,會稍後被傳遞給某一進行,而進程也會採取某些措施來響應信號,在產生和到達期間,信號處於等待(pending)狀態。如果需要確保一段代碼不爲傳遞來的信號所中斷,可將信號添加到信號掩碼中,會阻止該信號的到達,直到稍後對其解除阻塞。進程可以使用各種系統調用對其信號掩碼添加和移除信號。
信號到達後,進程視具體信號執行如下默認操作之一:
忽略信號:內核將信號丟棄
終止進程
產生核心轉儲文件,同時進程終止:核心轉儲文件包含對進程虛擬內存的鏡像,可將其加載到調試器中以檢查進程終止時的狀態
停止進程:暫停進程的執行
於之前暫停後再度恢復進程的執行
除了根據特定信號而採取默認行爲之外,程序也能改變信號到達時的響應行爲,稱爲對信號的處置設置。程序可以將對信號的初值設置爲如下之一:
採取默認行爲
忽略信號
執行信號處理器(信號處理器程序是由程序員編寫的函數,用於爲響應傳遞來的信號而執行適當任務)
改變信號處置:signal()
void (*signal(int sig, void (*handler)(int)))(int);
關於signal()函數的聲明理解可以參考文章分析C聲明
#include <signal.h>
#include "tlpi_hdr.h"
static void sigHandler(int sig)
{
printf("Ouch!\n"); /* UNSAFE (see Section 21.1.2) */
}
int main(int argc, char *argv[])
{
int j;
if (signal(SIGINT, sigHandler) == SIG_ERR)
errExit("signal");
for (j = 0; ; j++) {
printf("%d\n", j);
sleep(3); /* Loop slowly... */
}
}