一. 信號產生的場景
???? 1. 用戶輸入命令, 在shell 啟動一個前臺進程
???? 2. 當用戶按一下 Ctrl + C 的時候,從鍵盤產生一個硬件中斷
???? 3. 此時CPU 正在執行這個進程的帶代碼, 則該進程的執行代碼暫停執行, CPU 從用戶態切換到內核態處理該硬件中斷.
???? 4. 中斷驅動程序將Ctrl + C 解釋為一個 SIGIN 信號, 記在該進程的 PCB 中(操作系統給進程法送了一個 SUGIN 信號)
???? 5. 當操作系統要從內核返回到該進程的代碼繼續執行之前, 首先要處理PCB中記錄的信號, 發現了一個 SUGIN 信號, 而該信號的默認處理動作是終止進程, 所以此時進程直接終止, 不再返回.
注意:
????1. Ctr + C 只能發給一個前臺正在運行的進程, 一個命令后加 & 便可以將該進程放在后臺取執行, 這樣shell就不用等待進程結束便可以啟動新的進程
????2. shell 可以一次執行一個前臺進程, 但可以一次執行多個后臺進程, 只有前臺信號才能接受控制鍵產生的信號
????3. 進程在運行的如何時候都可以接到像 Ctr + C 的這種鍵盤控制信號而終止, 因此信號相對于進程而言是異步的.
查看信號的命令: kill -l
????其中前 31 個信號屬于普通信號, 沒有 32 和 33 號信號, Ctrl + C 產生 11 號 SIGSEGV 信號, Ctrl + Z 產生 SIGTSTP 20 號信號, Ctrl + / 產生 SIGQUIT 3 號信號.
二. 信號產生的幾種方式
????1. 用戶在終端鍵盤產生中斷,終端驅動程序會發送信號給當前前臺進程,.
????2. 硬件異常產生中斷,如執行除以 0 的操作, 此時 CPU 運算單元產生異常, 內核將這個異常解釋為一個 SUGFPE 發送給該前臺進程, 或者當程序訪問了非法內存時, 此時MMU產生一個異常, 內核將這個異常解釋為 SIGSEGV 發送給該進程.
????3. 通過命令給當前進程發送信號 kill -11 test(給test進程發送 11 號信號)
????4. 軟件條件產生異常, 如管道讀寫時, 讀端關閉, 此時寫端還在繼續寫, 此時,操作系統會給當前進程發送一個 13 號信號, 進程發現這個信號, 退出.
三. 調用系統函數給信號發送信號
????1.kill -信號編號 進程編號
????2.kill -信號名 進程編號
????????????????
????該進程是一個死循環的程序, 但此時給該進程發送一個11號信號, 這個信號在進程眼里就是一個SIGEGV 信號, 進程收到這個信號的默認執行動作是終止信號, 并且給用戶發送段錯誤提示信息.
????3. kill 命令的函數實現
????????????????????????????????
????其中 pid 指的是該進程的 pid, sig 指的是需要發送的信號的編號.
????kill 函數用來給對應進程發送一個編號為 sig 的信號
????raise 函數用來給當前進程發送一個編號為 signo 的信號
????abort 函數是是當前信號接收到信號而異常終止
四. 軟件條件產生信號
?????????????????????????????
????用來設定一個鬧鐘, 告訴內核在 seconds 秒之后給進程發送一個SIGALRM 信號, 該信號的默認執行動作時終止當前進程. 函數的返回值是 0 或者是以前設定的鬧鐘時間還余下的秒數.如果將 seconds 設為 0, 表示取消以前設定的鬧鐘,鬧鐘的返回值任然是以前設定的鬧鐘剩余的秒數.