訊號:linux的訊號機制是從unix的基礎上發展來的,在linux中一共有64個訊號(實際只有62個,另外兩個被廢棄了),其中前32是從unix中繼承來的,用來控制程序。另外32個是liunx的訊號有被稱為實時訊號,用來操作硬體。
在linux系統中通過kill -l命令可以檢視這寫訊號:
作業系統對訊號的處理一般有3種方式:
一、預設 二、忽略 三、捕捉
預設方式:作業系統為每個程序都設定了預設的動作(5種),當程序接收到訊號後系統就會使用該訊號對應的動作。
這五種動作分別是:
(1)term:終止當前程序。
(2)core:終止當前程序並且生成core檔案(用於gdb除錯)
(3)ign: 忽略該訊號
(4)stop:暫停當前程序
(5)cont:繼續執行暫停的程式。
(*最後一行為該訊號在什麼情況下會產生)
通過man 7 signal 命令可以檢視signal的具體資訊。
忽略方式:當某個程序接收到訊號,會忽略它,即不去處理。一般的訊號都可以被設定忽略,但sigkill和sigstop是不能被忽略。(如果可以忽略就會產出核心無法殺死的程序,這會非常的危險)。
捕捉方式:即當程序接收到訊號後,不會去使用預設的方法,而是使用使用者自定義的方式去處理這個訊號。
那訊號是如何產生的那?
訊號編號
訊號名稱
產生原因
1sighup
當使用者退出shell時,由該shell啟動的所有程序將收到這個訊號,預設動作為終止程序
2sigint
當使用者按下ctrl+c組合鍵時,使用者終端向該終端啟動並正在執行的程序傳送此訊號,預設終止程序
3sigquit
當使用者按下ctrl+\組合鍵時,使用者終端向該終端啟動並正在執行的程序傳送此訊號,預設終止程序
4sigill
cpu檢測到某程序執行了非法指令。預設終止程序並產生core檔案
5sigtrap
由斷點或者其他trap指令產生
6sigabrt
呼叫abort函式時產生
7sigbus
非法訪問記憶體位址,包括記憶體對齊出錯
8sigfpe
在發生致命的運算錯誤時發出。包括浮點數運算錯誤,溢位及除數為0等所有演算法錯誤
9sigkill
無條件終止程序
10siguse1
使用者自定義訊號,可以在程式中使用
11sigse**
無效記憶體訪問
12sigusr2
使用者自定義訊號,可以在程式中使用
13sigpipe
向沒有讀端的管道寫資料
14sigalrm
定時器超時
15sigterm
程式結束訊號
16sigstkflt
linux專用,數學協處理器的棧異常
17sigchid
子程序結束時,父程序接收的訊號
18sigcont
繼續執行暫停程序執行
19sigstop
暫停乙個程序
20sigtstp
互動停止程序(ctrl+z)
21sigttin
當乙個後台程序試圖讀控制終端時,終端驅動程式產生
22sigttou
當乙個後台程序試圖寫控制終端時,終端驅動程式產生
23sigurg
通知程序已經發生了乙個緊急情況。在網路連線上接到非規定的波特率的資料時,此訊號可選擇的產生。
24sigxcpu
當cpu時間限制超時的時候
25sigxfsz
超過檔案的最大長度設定。
26si**talrm
虛擬時鐘超時時產生該訊號,只計算cpu使用時間
27sigprof
和si**talrm類似,計算cpu和執行系統呼叫的時間
28sigwinch
視窗大小發生變化時產生該訊號
29sigio
向程序發出乙個非同步的i/o事件
30siggpwr
關機31
sigsys
無效的系統呼叫
在程序的pcb中儲存兩個訊號集(未決訊號集和阻塞訊號集),當程序接收到乙個訊號時,作業系統核心會將該程序未決訊號集中的對應的訊號位置為1,表示這個訊號還沒有被真正的執行,然後去檢視對應的阻塞訊號集,如果阻塞訊號集中對應的狀態位為0,那麼該訊號執行,對應未決訊號集中的1重新置為0(遞達態)。如果為1,那麼這個訊號被阻塞。並且前32個訊號不支援排隊,即如果未決訊號集中的狀態一旦為1,那麼之後同樣的訊號不會被接收。後32為支援排隊。
這時我們知道如果需要忽略程序某個訊號,只需要將該程序對應的阻塞訊號集對應訊號位置上的狀態位置為1,就可以了,那具體如何操作那?實際上我們時無法直接去修改pcb中的阻塞訊號集的,不過linux系統為我們提供了訊號集處理的函式。
訊號集的處理函式:
sigset_t為訊號集(結構體,佔128個位元組,可以通過sizeof()檢視)
int sigemptyset(sigset_t *set); //將訊號集的狀態為全部置為0
int sigfillset(sigset_t *set); //將訊號集的狀態為全部置為1
int sigaddset(sigset_t *set); //將訊號集中指定的狀態置為1
int sigdelset(sigset_t *set); //將訊號集中指定的狀態置為0
int sigismember(const sigset_t *set,int signo);//檢視訊號集中對應訊號的狀態位
int sigprocmask(int how,const sigset_t *set,sigset_t *oset);
/*函式功能:讀取或更改程序的訊號阻塞訊號集
引數說明:
(1)how
sig_block :將set訊號集新增到當前訊號集,相當於 mask=mask|set
sig_unblock:使用set訊號集解除阻塞訊號集的訊號,相當於 mask=mask&(~set)
sig_setmask:將阻塞訊號集替換為set訊號集。相當於mask=set
(2)set
set訊號集,更改阻塞訊號集。
(3)oset
oset傳出引數,將阻塞訊號集通過oset傳出
返回值:
若成功返回0,出錯返回-1
*/
我們可以通過sigset_t定義乙個訊號集,然後通過相應的函式對訊號集進行設定,然後將它通過sigprocmask()函式註冊進系統中。
int sigpending(sigset_t *set);
/*函式功能:
讀取當前程序的未決訊號集,通過set引數傳出。
返回值:
成功返回0,失敗返回-1
*/
程式:設定阻塞sigint(ctrl+c)和sigquit (ctrl+\)10秒
linux學習之旅(1) Linux簡介
作業系統是什麼?作業系統 英語 operating system,縮寫作 os 是管理計算機硬體與軟體資源的電腦程式,同時也是計算機系統的核心與基石。作業系統需要處理如管理與配置記憶體 決定系統資源供需的優先次序 控制輸入與輸出裝置 操作網路與管理檔案系統等基本事務。作業系統也提供乙個讓使用者與系統...
萌新的linux之旅19
系統正常引導過程 如果引導程式boot損壞 446位元組是啟動引導 dd if dev zero of dev vda bs 446 count 1 注意一定是446 多了或少了都不能正常引導修復 保證selinux是disabled 然後重啟,發現一直在booting,即無法引導系統系統 關閉虛擬...
c primer plus 學習之旅 1
c語言的起源 1972年,貝爾實驗室的丹尼斯 里奇和肯 湯姆遜在開發unix作業系統時設計了c語言 可移植性及利害關係 由於c語言與unix關係密切,unix系統通常會將c編譯器作為軟體包的一部分。而windows系統底層是dos所以在一些大廠中要求linux 程式設計的7個步驟 編譯器和鏈結器 編...