Linux下的信號是一個什么概念呢。我們在現實生活中也遇到過信號之類的。比如紅綠信號燈,班主任叫你去辦公室并且臉色不好,諸如此類的都會給你一個信號。讓你辨別事情的發生。同樣,Linux下也有許多的信號,讓你執行相應的操作。比如我們經常使用的ctrl + c,ctrl + z,ctrl + d等,想結束掉當前的進程,我們通常使用ctrl + c,但是ctrl+c只適用于前臺進程,如果是切換到后臺進程的話,ctrl+c就終止不了。
我們寫了一個死循環的輸出“hello world”的例子,當我們使用ctrl+c的時候,相當于觸發了2號信號來中斷進程,當我們把它放到后臺運行的時候,使用ctrl+c根本不管用。因為它信號只能對前臺進程這樣操作。

那么我們怎么終止它呢。這些信號里邊有特殊的信號是可以終止后臺進程的,9號信號(SIGKILL),這就是kill信號的強大之處。(如果所有的進程都放在后臺,且都終止不了,那操作系統不得掛掉啊^_^哈哈)當然不只是9號信號可以對后臺進程操作,還有些也可以。只是9號信號大家經常用到。所以就多說幾句哈。(這里還要強調的一點是,shell不僅可以運行一個前臺進程,還可以運行任意多個后臺進程)

比如:
通過命令Kill -l,可以查看信號:

以上就是62個信號,其中1-31為普通信號,34-64為實時信號。
上面說了1-31號為普通信號,那么它可以用什么來表示呢。1和31這個敏感的數字,我們可以想到什么呢。是不是可以想到位圖。32個比特位,每一位表示一個信號存在或者不存在。這樣的話就只需要4個字節(也即一個整數)就可以存放這些信號了。
信號的處理動作主要有:
1.忽略該信號
2.執行該信號的默認處理動作
3.捕捉信號(自定義動作,自己定義的一些信號處理函數)
對于捕捉自定義信號,舉個栗子哈:

當我們觸發到2號信號時,我們就會執行自定義的信號處理函數,會打印出pid和sig值。而不再是終止進程。
結果如下:

小姿勢(哈哈):
信號具有異步的特點,主要體現在任何一個時刻都可能產生信號。
那么話題又來了,產生信號的條件有哪些呢?
(1)像剛剛產生的信號,是用鍵盤產生的。鍵盤按ctrl+c,ctrl+z,ctrl+d等等。
(2)還有可能是因為某一個異常觸發了某一個信號導致的。

比如上述這個題目,本來除數不能為0,這里讓被除數除以一個為0的數,此時就會拋出異常。

這里的這個異常就是段錯誤所導致的。
(3)由于系統調用接口產生信號。系統調用接口,主要有以下幾種:
1.自己寫一個kill函數,來調用kill函數或者直接調用系統的kill函數使其產生9號信號。
系統的kill:int kill(pid_t pid,int sig);
2.調用raise函數,自己給自己發信號。
3.調用abort函數,像exit一樣,觸發捕捉信號后終止進程。
1.kill函數(成功返回0,錯誤返回-1)

運行結果為:運行完5個hello world之后,將執行2號信號,因此進程退出。

在這里,如何自己定義一個mykill函數呢。

它會檢測你命令行上輸入的命令,如果錯誤,將會給你顯示出kill的正確用法。

上述用法錯誤,給你提示了。
比如先啟動一個進程:(本身是死循環)

然后我們將其殺死:(通過獲取進程號,這樣就模擬了系統的kill函數)

2.使用raise函數(成功返回0,錯誤返回-1)

此時,結果與上述一樣,只是raise為自己給自己發送2號信號。

3.使用abort函數(函數總會成功,所以沒有返回值)

運行結果為:

(4)通過軟件觸發產生信號。主要使用alarm函數來觸發SIGALRM信號。
unsigned int alarm(unsigned int seconds);
參數為秒數,多少秒之后觸發SIGALRM信號。

這個例子當3秒之后觸發alarm信號,終止進程
