信號能夠理解成一種軟件中斷。他提供了一種異步處理事件的方式。每一個信號都有一個與之對應的信號名,這些信號名都帶有SIG前綴,如:SIGABRT,SIGALARM。頭文件signal.h 中定義了全部的信號名,他們值爲正整數常量。事實上,實現將個別信號定義在不一樣的頭文件中,只不過這些頭文件又被包含在了signal.h中;這是由於內核不可能去包含應用於用戶級別程序的頭文件!所以,當用戶程序與內核同時須要某信息的定義時,一般的作法是把這個定義放到內核頭文件中,而後在用戶頭文件中包含這個內核頭文件。安全
unix系統信號列表:數據結構
當信號列表中的默認action爲「terminal+core」時,他意味着進程的內存映像會留在進程目錄下的core文件中。core文件能夠幫助大多數UNIX系統調試者來檢查進程終止時的狀態。可是,若是 a)進程設置了set-user-ID並且當前用戶不是進程文件的擁有者;或者 b)進程設置了 set-group-ID 並且當前用戶不是進程文件的用戶組擁有者;或者 c) 當前用戶下該用戶沒有寫入權;或者d) 此文件已存在並且當前用戶沒有寫入權;或者e)文件太大時core文件不會被建立。多線程
程序啓動異步
當一個程序被執行的時候,全部的信號的裝填要麼是默認方式處理要麼是忽略信號。一般,信號被設置爲它們的默認處理方法,除非調用exec的進程忽略了這個信號。詳細來講exec函數會將調用exec進程捕獲的信號的狀態更改成信號的默認處理方式而保留其餘信號的處理方式,由於exec執行的新程序中不包含捕獲信號的函數地址,因此這些處理方式在新程序中是無心義的。async
進程建立函數
當一個進程調用fork時,子進程繼承父進程的信號處理方式。在這裏,子進程是由父進程的內存鏡像的副本開始的,所以信號捕獲函數的地址是有意義的。spa
可重入函數線程
當一個信號一個進程的信號處理函數捕獲,此進程的正常指令執行順序會被此信號處理短暫的中斷,處理完信號後進程從以前被中斷的地方繼續執行。可是在信號處理函數中,咱們是沒法識別出當信號被捕獲是進程執行到了哪一步。若是當收到信號時進程正在經過malloc從堆上分配一塊額外的內存時,咱們應該怎麼辦呢,在信號處理函數中調用malloc嗎?亦或是當收到某個信號時咱們正在調用某個函數,好比getpwnam,這個函數將他的返回值存儲在一個靜態區域,這種狀況下咱們應該在信號處理函數中調用一樣的函數嗎?在上面malloc的情景中那樣作會對進程產生災難性的後果,由於malloc一般包含一個它全部分配過的區域的連接表,也許當時它正處於更新這個連接表的狀態中。在getpwnam的情境下,存儲在靜態區的getpwnam的返回值會被信號處理函數中的調用結果重寫!unix
所以, The Single UNIX Specification 要求信號處理函數中的函數調用必須是安全的,便可重入的(Reentrant functions)。這些函數被 The Single Unix Specification稱爲異步信號安全函數(async-signal safe)。除了可重入,他們會在函數運行期間阻塞任何會破壞連續性的信號的下達。異步信號安全函數列表以下:調試
一些函數不被稱爲異步信號安全的緣由大體以下:
大多數標準I/O庫的實現使用了靜態數據結構,他們都不是可重入函數。須要特別注意的一點是:即便咱們在信號處理函數中使用異步信號安全的函數,每一個線程下也僅僅只有一個errno變量(在多線程環境下,多個線程共享進程地址空間。每一個線程須要它本身的errno副本以阻止線程間的相互干擾),而咱們可能會潛在的修改掉errno的值。所以,有個通則:在信號處理函數中調用異步信號安全函數前,應當保存errno。