linux 信号(signal)介绍
生活随笔
收集整理的這篇文章主要介紹了
linux 信号(signal)介绍
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
信號(hào)是
Linux編程中非常重要的部分,本文將詳細(xì)介紹信號(hào)機(jī)制的基本概念、Linux對(duì)信號(hào)機(jī)制的大致實(shí)現(xiàn)方法、如何使用信號(hào),以及有關(guān)信號(hào)的幾個(gè)系統(tǒng)調(diào)用。
信號(hào)機(jī)制是進(jìn)程之間相互傳遞消息的一種方法,信號(hào)全稱為軟中斷信號(hào),也有人稱作軟中斷。從它的命名可以看出,它的實(shí)質(zhì)和使用很象中斷。所以,信號(hào)可以說是進(jìn)程控制的一部分。
一、信號(hào)的基本概念
本節(jié)先介紹信號(hào)的一些基本概念,然后給出一些基本的信號(hào)類型和信號(hào)對(duì)應(yīng)的事件。基本概念對(duì)于理解和使用信號(hào),對(duì)于理解信號(hào)機(jī)制都特別重要。下面就來看看什么是信號(hào)。
1、基本概念
軟中斷信號(hào)(signal,又簡(jiǎn)稱為信號(hào))用來通知進(jìn)程發(fā)生了異步事件。進(jìn)程之間可以互相通過系統(tǒng)調(diào)用kill發(fā)送軟中斷信號(hào)。內(nèi)核也可以因?yàn)閮?nèi)部事件而給進(jìn)程發(fā)送信號(hào),通知進(jìn)程發(fā)生了某個(gè)事件。注意,信號(hào)只是用來通知某進(jìn)程發(fā)生了什么事件,并不給該進(jìn)程傳遞任何數(shù)據(jù)。
收到信號(hào)的進(jìn)程對(duì)各種信號(hào)有不同的處理方法。處理方法可以分為三類:第一種是類似中斷的處理程序,對(duì)于需要處理的信號(hào),進(jìn)程可以指定處理函數(shù),由該函數(shù)來處理。第二種方法是,忽略某個(gè)信號(hào),對(duì)該信號(hào)不做任何處理,就象未發(fā)生過一樣。第三種方法是,對(duì)該信號(hào)的處理保留系統(tǒng)的默認(rèn)值,這種缺省操作,對(duì)大部分的信號(hào)的缺省操作是使得進(jìn)程終止。進(jìn)程通過系統(tǒng)調(diào)用signal來指定進(jìn)程對(duì)某個(gè)信號(hào)的處理行為。
在進(jìn)程表的表項(xiàng)中有一個(gè)軟中斷信號(hào)域,該域中每一位對(duì)應(yīng)一個(gè)信號(hào),當(dāng)有信號(hào)發(fā)送給進(jìn)程時(shí),對(duì)應(yīng)位置位。由此可以看出,進(jìn)程對(duì)不同的信號(hào)可以同時(shí)保留,但對(duì)于同一個(gè)信號(hào),進(jìn)程并不知道在處理之前來過多少個(gè)。
2、信號(hào)的類型
發(fā)出信號(hào)的原因很多,這里按發(fā)出信號(hào)的原因簡(jiǎn)單分類,以了解各種信號(hào):
(1) 與進(jìn)程終止相關(guān)的信號(hào)。當(dāng)進(jìn)程退出,或者子進(jìn)程終止時(shí),發(fā)出這類信號(hào)。
(2) 與進(jìn)程例外事件相關(guān)的信號(hào)。如進(jìn)程越界,或企圖寫一個(gè)只讀的內(nèi)存區(qū)域(如程序正文區(qū)),或執(zhí)行一個(gè)特權(quán)指令及其他各種硬件錯(cuò)誤。
(3) 與在系統(tǒng)調(diào)用期間遇到不可恢復(fù)條件相關(guān)的信號(hào)。如執(zhí)行系統(tǒng)調(diào)用exec時(shí),原有資源已經(jīng)釋放,而目前系統(tǒng)資源又已經(jīng)耗盡。
(4) 與執(zhí)行系統(tǒng)調(diào)用時(shí)遇到非預(yù)測(cè)錯(cuò)誤條件相關(guān)的信號(hào)。如執(zhí)行一個(gè)并不存在的系統(tǒng)調(diào)用。
(5) 在用戶態(tài)下的進(jìn)程發(fā)出的信號(hào)。如進(jìn)程調(diào)用系統(tǒng)調(diào)用kill向其他進(jìn)程發(fā)送信號(hào)。
(6) 與終端交互相關(guān)的信號(hào)。如用戶關(guān)閉一個(gè)終端,或按下break鍵等情況。
(7) 跟蹤進(jìn)程執(zhí)行的信號(hào)。
Linux支持的信號(hào)列表如下。很多信號(hào)是與機(jī)器的體系結(jié)構(gòu)相關(guān)的,首先列出的是POSIX.1中列出的信號(hào):
信號(hào) 值 處理動(dòng)作 發(fā)出信號(hào)的原因
----------------------------------------------------------------------
SIGHUP 1 A 終端掛起或者控制進(jìn)程終止
SIGINT 2 A 鍵盤中斷(如break鍵被按下)
SIGQU99v 3 C 鍵盤的退出鍵被按下
SIGILL 4 C 非法指令
SIGABRT 6 C 由abort(3)發(fā)出的退出指令
SIGFPE 8 C 浮點(diǎn)異常
SIGKILL 9 AEF Kill信號(hào)
SIGSEGV 11 C 無效的內(nèi)存引用
SIGPIPE 13 A 管道破裂: 寫一個(gè)沒有讀端口的管道
SIGALRM 14 A 由alarm(2)發(fā)出的信號(hào)
SIGTERM 15 A 終止信號(hào)
SIGUSR1 30,10,16 A 用戶自定義信號(hào)1
SIGUSR2 31,12,17 A 用戶自定義信號(hào)2
SIGCHLD 20,17,18 B 子進(jìn)程結(jié)束信號(hào)
SIGCONT 19,18,25 進(jìn)程繼續(xù)(曾被停止的進(jìn)程)
SIGSTOP 17,19,23 DEF 終止進(jìn)程
SIGTSTP 18,20,24 D 控制終端(tty)上按下停止鍵
SIGTTIN 21,21,26 D 后臺(tái)進(jìn)程企圖從控制終端讀
SIGTTOU 22,22,27 D 后臺(tái)進(jìn)程企圖從控制終端寫
下面的信號(hào)沒在POSIX.1中列出,而在SUSv2列出
信號(hào) 值 處理動(dòng)作 發(fā)出信號(hào)的原因
--------------------------------------------------------------------
SIGBUS 10,7,10 C 總線錯(cuò)誤(錯(cuò)誤的內(nèi)存訪問)
SIGPOLL A Sys V定義的Pollable事件,與SIGIO同義
SIGPROF 27,27,29 A Profiling定時(shí)器到
SIGSYS 12,-,12 C 無效的系統(tǒng)調(diào)用 (SVID)
SIGTRAP 5 C 跟蹤/斷點(diǎn)捕獲
SIGURG 16,23,21 B Socket出現(xiàn)緊急條件(4.2 BSD)
SIGVTALRM 26,26,28 A 實(shí)際時(shí)間報(bào)警時(shí)鐘信號(hào)(4.2 BSD)
SIGXCPU 24,24,30 C 超出設(shè)定的CPU時(shí)間限制(4.2 BSD)
SIGXFSZ 25,25,31 C 超出設(shè)定的文件大小限制(4.2 BSD)
(對(duì)于SIGSYS,SIGXCPU,SIGXFSZ,以及某些機(jī)器體系結(jié)構(gòu)下的SIGBUS,Linux缺省的動(dòng)作是A (terminate),SUSv2 是C (terminate and dump core))。
下面是其它的一些信號(hào)
信號(hào) 值 處理動(dòng)作 發(fā)出信號(hào)的原因
----------------------------------------------------------------------
SIGIOT 6 C IO捕獲指令,與SIGABRT同義
SIGEMT 7,-,7
SIGSTKFLT -,16,- A 協(xié)處理器堆棧錯(cuò)誤
SIGIO 23,29,22 A 某I/O操作現(xiàn)在可以進(jìn)行了(4.2 BSD)
SIGCLD -,-,18 A 與SIGCHLD同義
SIGPWR 29,30,19 A 電源故障(System V)
SIGINFO 29,-,- A 與SIGPWR同義
SIGLOST -,-,- A 文件鎖丟失
SIGWINCH 28,28,20 B 窗口大小改變(4.3 BSD, Sun)
SIGUNUSED -,31,- A 未使用的信號(hào)(will be SIGSYS)
(在這里,- 表示信號(hào)沒有實(shí)現(xiàn);有三個(gè)值給出的含義為,第一個(gè)值通常在Alpha和Sparc上有效,中間的值對(duì)應(yīng)i386和ppc以及sh,最后一個(gè)值對(duì)應(yīng)mips。信號(hào)29在Alpha上為SIGINFO / SIGPWR ,在Sparc上為SIGLOST。)
處理動(dòng)作一項(xiàng)中的字母含義如下
A 缺省的動(dòng)作是終止進(jìn)程
B 缺省的動(dòng)作是忽略此信號(hào)
C 缺省的動(dòng)作是終止進(jìn)程并進(jìn)行內(nèi)核映像轉(zhuǎn)儲(chǔ)(dump core)
D 缺省的動(dòng)作是停止進(jìn)程
E 信號(hào)不能被捕獲
F 信號(hào)不能被忽略
上面介紹的信號(hào)是常見系統(tǒng)所支持的。以表格的形式介紹了各種信號(hào)的名稱、作用及其在默認(rèn)情況下的處理動(dòng)作。各種默認(rèn)處理動(dòng)作的含義是:終止程序是指進(jìn)程退出;忽略該信號(hào)是將該信號(hào)丟棄,不做處理;停止程序是指程序掛起,進(jìn)入停止?fàn)顩r以后還能重新進(jìn)行下去,一般是在調(diào)試的過程中(例如ptrace系統(tǒng)調(diào)用);內(nèi)核映像轉(zhuǎn)儲(chǔ)是指將進(jìn)程數(shù)據(jù)在內(nèi)存的映像和進(jìn)程在內(nèi)核結(jié)構(gòu)中存儲(chǔ)的部分內(nèi)容以一定格式轉(zhuǎn)儲(chǔ)到文件系統(tǒng),并且進(jìn)程退出執(zhí)行,這樣做的好處是為程序員提供了方便,使得他們可以得到進(jìn)程當(dāng)時(shí)執(zhí)行時(shí)的數(shù)據(jù)值,允許他們確定轉(zhuǎn)儲(chǔ)的原因,并且可以調(diào)試他們的程序。
注意 信號(hào)SIGKILL和SIGSTOP既不能被捕捉,也不能被忽略。信號(hào)SIGIOT與SIGABRT是一個(gè)信號(hào)。可以看出,同一個(gè)信號(hào)在不同的系統(tǒng)中值可能不一樣,所以建議最好使用為信號(hào)定義的名字,而不要直接使用信號(hào)的值。
二、信 號(hào) 機(jī) 制
上一節(jié)中介紹了信號(hào)的基本概念,在這一節(jié)中,我們將介紹內(nèi)核如何實(shí)現(xiàn)信號(hào)機(jī)制。即內(nèi)核如何向一個(gè)進(jìn)程發(fā)送信號(hào)、進(jìn)程如何接收一個(gè)信號(hào)、進(jìn)程怎樣控制自己對(duì)信號(hào)的反應(yīng)、內(nèi)核在什么時(shí)機(jī)處理和怎樣處理進(jìn)程收到的信號(hào)。還要介紹一下setjmp和longjmp在信號(hào)中起到的作用。
1、內(nèi)核對(duì)信號(hào)的基本處理方法
內(nèi)核給一個(gè)進(jìn)程發(fā)送軟中斷信號(hào)的方法,是在進(jìn)程所在的進(jìn)程表項(xiàng)的信號(hào)域設(shè)置對(duì)應(yīng)于該信號(hào)的位。這里要補(bǔ)充的是,如果信號(hào)發(fā)送給一個(gè)正在睡眠的進(jìn)程,那么要看該進(jìn)程進(jìn)入睡眠的優(yōu)先級(jí),如果進(jìn)程睡眠在可被中斷的優(yōu)先級(jí)上,則喚醒進(jìn)程;否則僅設(shè)置進(jìn)程表中信號(hào)域相應(yīng)的位,而不喚醒進(jìn)程。這一點(diǎn)比較重要,因?yàn)檫M(jìn)程檢查是否收到信號(hào)的時(shí)機(jī)是:一個(gè)進(jìn)程在即將從內(nèi)核態(tài)返回到用戶態(tài)時(shí);或者,在一個(gè)進(jìn)程要進(jìn)入或離開一個(gè)適當(dāng)?shù)牡驼{(diào)度優(yōu)先級(jí)睡眠狀態(tài)時(shí)。
內(nèi)核處理一個(gè)進(jìn)程收到的信號(hào)的時(shí)機(jī)是在一個(gè)進(jìn)程從內(nèi)核態(tài)返回用戶態(tài)時(shí)。所以,當(dāng)一個(gè)進(jìn)程在內(nèi)核態(tài)下運(yùn)行時(shí),軟中斷信號(hào)并不立即起作用,要等到將返回用戶態(tài)時(shí)才處理。進(jìn)程只有處理完信號(hào)才會(huì)返回用戶態(tài),進(jìn)程在用戶態(tài)下不會(huì)有未處理完的信號(hào)。
內(nèi)核處理一個(gè)進(jìn)程收到的軟中斷信號(hào)是在該進(jìn)程的上下文中,因此,進(jìn)程必須處于運(yùn)行狀態(tài)。前面介紹概念的時(shí)候講過,處理信號(hào)有三種類型:進(jìn)程接收到信號(hào)后退出;進(jìn)程忽略該信號(hào);進(jìn)程收到信號(hào)后執(zhí)行用戶設(shè)定用系統(tǒng)調(diào)用signal的函數(shù)。當(dāng)進(jìn)程接收到一個(gè)它忽略的信號(hào)時(shí),進(jìn)程丟棄該信號(hào),就象沒有收到該信號(hào)似的繼續(xù)運(yùn)行。如果進(jìn)程收到一個(gè)要捕捉的信號(hào),那么進(jìn)程從內(nèi)核態(tài)返回用戶態(tài)時(shí)執(zhí)行用戶定義的函數(shù)。而且執(zhí)行用戶定義的函數(shù)的方法很巧妙,內(nèi)核是在用戶棧上創(chuàng)建一個(gè)新的層,該層中將返回地址的值設(shè)置成用戶定義的處理函數(shù)的地址,這樣進(jìn)程從內(nèi)核返回彈出棧頂時(shí)就返回到用戶定義的函數(shù)處,從函數(shù)返回再彈出棧頂時(shí),才返回原先進(jìn)入內(nèi)核的地方。這樣做的原因是用戶定義的處理函數(shù)不能且不允許在內(nèi)核態(tài)下執(zhí)行(如果用戶定義的函數(shù)在內(nèi)核態(tài)下運(yùn)行的話,用戶就可以獲得任何權(quán)限)。
在信號(hào)的處理方法中有幾點(diǎn)特別要引起注意。第一,在一些系統(tǒng)中,當(dāng)一個(gè)進(jìn)程處理完中斷信號(hào)返回用戶態(tài)之前,內(nèi)核清除用戶區(qū)中設(shè)定的對(duì)該信號(hào)的處理例程的地址,即下一次進(jìn)程對(duì)該信號(hào)的處理方法又改為默認(rèn)值,除非在下一次信號(hào)到來之前再次使用signal系統(tǒng)調(diào)用。這可能會(huì)使得進(jìn)程在調(diào)用signal之前又得到該信號(hào)而導(dǎo)致退出。在BSD中,內(nèi)核不再清除該地址。但不清除該地址可能使得
一、信號(hào)的基本概念
本節(jié)先介紹信號(hào)的一些基本概念,然后給出一些基本的信號(hào)類型和信號(hào)對(duì)應(yīng)的事件。基本概念對(duì)于理解和使用信號(hào),對(duì)于理解信號(hào)機(jī)制都特別重要。下面就來看看什么是信號(hào)。
1、基本概念
軟中斷信號(hào)(signal,又簡(jiǎn)稱為信號(hào))用來通知進(jìn)程發(fā)生了異步事件。進(jìn)程之間可以互相通過系統(tǒng)調(diào)用kill發(fā)送軟中斷信號(hào)。內(nèi)核也可以因?yàn)閮?nèi)部事件而給進(jìn)程發(fā)送信號(hào),通知進(jìn)程發(fā)生了某個(gè)事件。注意,信號(hào)只是用來通知某進(jìn)程發(fā)生了什么事件,并不給該進(jìn)程傳遞任何數(shù)據(jù)。
收到信號(hào)的進(jìn)程對(duì)各種信號(hào)有不同的處理方法。處理方法可以分為三類:第一種是類似中斷的處理程序,對(duì)于需要處理的信號(hào),進(jìn)程可以指定處理函數(shù),由該函數(shù)來處理。第二種方法是,忽略某個(gè)信號(hào),對(duì)該信號(hào)不做任何處理,就象未發(fā)生過一樣。第三種方法是,對(duì)該信號(hào)的處理保留系統(tǒng)的默認(rèn)值,這種缺省操作,對(duì)大部分的信號(hào)的缺省操作是使得進(jìn)程終止。進(jìn)程通過系統(tǒng)調(diào)用signal來指定進(jìn)程對(duì)某個(gè)信號(hào)的處理行為。
在進(jìn)程表的表項(xiàng)中有一個(gè)軟中斷信號(hào)域,該域中每一位對(duì)應(yīng)一個(gè)信號(hào),當(dāng)有信號(hào)發(fā)送給進(jìn)程時(shí),對(duì)應(yīng)位置位。由此可以看出,進(jìn)程對(duì)不同的信號(hào)可以同時(shí)保留,但對(duì)于同一個(gè)信號(hào),進(jìn)程并不知道在處理之前來過多少個(gè)。
2、信號(hào)的類型
發(fā)出信號(hào)的原因很多,這里按發(fā)出信號(hào)的原因簡(jiǎn)單分類,以了解各種信號(hào):
(1) 與進(jìn)程終止相關(guān)的信號(hào)。當(dāng)進(jìn)程退出,或者子進(jìn)程終止時(shí),發(fā)出這類信號(hào)。
(2) 與進(jìn)程例外事件相關(guān)的信號(hào)。如進(jìn)程越界,或企圖寫一個(gè)只讀的內(nèi)存區(qū)域(如程序正文區(qū)),或執(zhí)行一個(gè)特權(quán)指令及其他各種硬件錯(cuò)誤。
(3) 與在系統(tǒng)調(diào)用期間遇到不可恢復(fù)條件相關(guān)的信號(hào)。如執(zhí)行系統(tǒng)調(diào)用exec時(shí),原有資源已經(jīng)釋放,而目前系統(tǒng)資源又已經(jīng)耗盡。
(4) 與執(zhí)行系統(tǒng)調(diào)用時(shí)遇到非預(yù)測(cè)錯(cuò)誤條件相關(guān)的信號(hào)。如執(zhí)行一個(gè)并不存在的系統(tǒng)調(diào)用。
(5) 在用戶態(tài)下的進(jìn)程發(fā)出的信號(hào)。如進(jìn)程調(diào)用系統(tǒng)調(diào)用kill向其他進(jìn)程發(fā)送信號(hào)。
(6) 與終端交互相關(guān)的信號(hào)。如用戶關(guān)閉一個(gè)終端,或按下break鍵等情況。
(7) 跟蹤進(jìn)程執(zhí)行的信號(hào)。
Linux支持的信號(hào)列表如下。很多信號(hào)是與機(jī)器的體系結(jié)構(gòu)相關(guān)的,首先列出的是POSIX.1中列出的信號(hào):
信號(hào) 值 處理動(dòng)作 發(fā)出信號(hào)的原因
----------------------------------------------------------------------
SIGHUP 1 A 終端掛起或者控制進(jìn)程終止
SIGINT 2 A 鍵盤中斷(如break鍵被按下)
SIGQU99v 3 C 鍵盤的退出鍵被按下
SIGILL 4 C 非法指令
SIGABRT 6 C 由abort(3)發(fā)出的退出指令
SIGFPE 8 C 浮點(diǎn)異常
SIGKILL 9 AEF Kill信號(hào)
SIGSEGV 11 C 無效的內(nèi)存引用
SIGPIPE 13 A 管道破裂: 寫一個(gè)沒有讀端口的管道
SIGALRM 14 A 由alarm(2)發(fā)出的信號(hào)
SIGTERM 15 A 終止信號(hào)
SIGUSR1 30,10,16 A 用戶自定義信號(hào)1
SIGUSR2 31,12,17 A 用戶自定義信號(hào)2
SIGCHLD 20,17,18 B 子進(jìn)程結(jié)束信號(hào)
SIGCONT 19,18,25 進(jìn)程繼續(xù)(曾被停止的進(jìn)程)
SIGSTOP 17,19,23 DEF 終止進(jìn)程
SIGTSTP 18,20,24 D 控制終端(tty)上按下停止鍵
SIGTTIN 21,21,26 D 后臺(tái)進(jìn)程企圖從控制終端讀
SIGTTOU 22,22,27 D 后臺(tái)進(jìn)程企圖從控制終端寫
下面的信號(hào)沒在POSIX.1中列出,而在SUSv2列出
信號(hào) 值 處理動(dòng)作 發(fā)出信號(hào)的原因
--------------------------------------------------------------------
SIGBUS 10,7,10 C 總線錯(cuò)誤(錯(cuò)誤的內(nèi)存訪問)
SIGPOLL A Sys V定義的Pollable事件,與SIGIO同義
SIGPROF 27,27,29 A Profiling定時(shí)器到
SIGSYS 12,-,12 C 無效的系統(tǒng)調(diào)用 (SVID)
SIGTRAP 5 C 跟蹤/斷點(diǎn)捕獲
SIGURG 16,23,21 B Socket出現(xiàn)緊急條件(4.2 BSD)
SIGVTALRM 26,26,28 A 實(shí)際時(shí)間報(bào)警時(shí)鐘信號(hào)(4.2 BSD)
SIGXCPU 24,24,30 C 超出設(shè)定的CPU時(shí)間限制(4.2 BSD)
SIGXFSZ 25,25,31 C 超出設(shè)定的文件大小限制(4.2 BSD)
(對(duì)于SIGSYS,SIGXCPU,SIGXFSZ,以及某些機(jī)器體系結(jié)構(gòu)下的SIGBUS,Linux缺省的動(dòng)作是A (terminate),SUSv2 是C (terminate and dump core))。
下面是其它的一些信號(hào)
信號(hào) 值 處理動(dòng)作 發(fā)出信號(hào)的原因
----------------------------------------------------------------------
SIGIOT 6 C IO捕獲指令,與SIGABRT同義
SIGEMT 7,-,7
SIGSTKFLT -,16,- A 協(xié)處理器堆棧錯(cuò)誤
SIGIO 23,29,22 A 某I/O操作現(xiàn)在可以進(jìn)行了(4.2 BSD)
SIGCLD -,-,18 A 與SIGCHLD同義
SIGPWR 29,30,19 A 電源故障(System V)
SIGINFO 29,-,- A 與SIGPWR同義
SIGLOST -,-,- A 文件鎖丟失
SIGWINCH 28,28,20 B 窗口大小改變(4.3 BSD, Sun)
SIGUNUSED -,31,- A 未使用的信號(hào)(will be SIGSYS)
(在這里,- 表示信號(hào)沒有實(shí)現(xiàn);有三個(gè)值給出的含義為,第一個(gè)值通常在Alpha和Sparc上有效,中間的值對(duì)應(yīng)i386和ppc以及sh,最后一個(gè)值對(duì)應(yīng)mips。信號(hào)29在Alpha上為SIGINFO / SIGPWR ,在Sparc上為SIGLOST。)
處理動(dòng)作一項(xiàng)中的字母含義如下
A 缺省的動(dòng)作是終止進(jìn)程
B 缺省的動(dòng)作是忽略此信號(hào)
C 缺省的動(dòng)作是終止進(jìn)程并進(jìn)行內(nèi)核映像轉(zhuǎn)儲(chǔ)(dump core)
D 缺省的動(dòng)作是停止進(jìn)程
E 信號(hào)不能被捕獲
F 信號(hào)不能被忽略
上面介紹的信號(hào)是常見系統(tǒng)所支持的。以表格的形式介紹了各種信號(hào)的名稱、作用及其在默認(rèn)情況下的處理動(dòng)作。各種默認(rèn)處理動(dòng)作的含義是:終止程序是指進(jìn)程退出;忽略該信號(hào)是將該信號(hào)丟棄,不做處理;停止程序是指程序掛起,進(jìn)入停止?fàn)顩r以后還能重新進(jìn)行下去,一般是在調(diào)試的過程中(例如ptrace系統(tǒng)調(diào)用);內(nèi)核映像轉(zhuǎn)儲(chǔ)是指將進(jìn)程數(shù)據(jù)在內(nèi)存的映像和進(jìn)程在內(nèi)核結(jié)構(gòu)中存儲(chǔ)的部分內(nèi)容以一定格式轉(zhuǎn)儲(chǔ)到文件系統(tǒng),并且進(jìn)程退出執(zhí)行,這樣做的好處是為程序員提供了方便,使得他們可以得到進(jìn)程當(dāng)時(shí)執(zhí)行時(shí)的數(shù)據(jù)值,允許他們確定轉(zhuǎn)儲(chǔ)的原因,并且可以調(diào)試他們的程序。
注意 信號(hào)SIGKILL和SIGSTOP既不能被捕捉,也不能被忽略。信號(hào)SIGIOT與SIGABRT是一個(gè)信號(hào)。可以看出,同一個(gè)信號(hào)在不同的系統(tǒng)中值可能不一樣,所以建議最好使用為信號(hào)定義的名字,而不要直接使用信號(hào)的值。
二、信 號(hào) 機(jī) 制
上一節(jié)中介紹了信號(hào)的基本概念,在這一節(jié)中,我們將介紹內(nèi)核如何實(shí)現(xiàn)信號(hào)機(jī)制。即內(nèi)核如何向一個(gè)進(jìn)程發(fā)送信號(hào)、進(jìn)程如何接收一個(gè)信號(hào)、進(jìn)程怎樣控制自己對(duì)信號(hào)的反應(yīng)、內(nèi)核在什么時(shí)機(jī)處理和怎樣處理進(jìn)程收到的信號(hào)。還要介紹一下setjmp和longjmp在信號(hào)中起到的作用。
1、內(nèi)核對(duì)信號(hào)的基本處理方法
內(nèi)核給一個(gè)進(jìn)程發(fā)送軟中斷信號(hào)的方法,是在進(jìn)程所在的進(jìn)程表項(xiàng)的信號(hào)域設(shè)置對(duì)應(yīng)于該信號(hào)的位。這里要補(bǔ)充的是,如果信號(hào)發(fā)送給一個(gè)正在睡眠的進(jìn)程,那么要看該進(jìn)程進(jìn)入睡眠的優(yōu)先級(jí),如果進(jìn)程睡眠在可被中斷的優(yōu)先級(jí)上,則喚醒進(jìn)程;否則僅設(shè)置進(jìn)程表中信號(hào)域相應(yīng)的位,而不喚醒進(jìn)程。這一點(diǎn)比較重要,因?yàn)檫M(jìn)程檢查是否收到信號(hào)的時(shí)機(jī)是:一個(gè)進(jìn)程在即將從內(nèi)核態(tài)返回到用戶態(tài)時(shí);或者,在一個(gè)進(jìn)程要進(jìn)入或離開一個(gè)適當(dāng)?shù)牡驼{(diào)度優(yōu)先級(jí)睡眠狀態(tài)時(shí)。
內(nèi)核處理一個(gè)進(jìn)程收到的信號(hào)的時(shí)機(jī)是在一個(gè)進(jìn)程從內(nèi)核態(tài)返回用戶態(tài)時(shí)。所以,當(dāng)一個(gè)進(jìn)程在內(nèi)核態(tài)下運(yùn)行時(shí),軟中斷信號(hào)并不立即起作用,要等到將返回用戶態(tài)時(shí)才處理。進(jìn)程只有處理完信號(hào)才會(huì)返回用戶態(tài),進(jìn)程在用戶態(tài)下不會(huì)有未處理完的信號(hào)。
內(nèi)核處理一個(gè)進(jìn)程收到的軟中斷信號(hào)是在該進(jìn)程的上下文中,因此,進(jìn)程必須處于運(yùn)行狀態(tài)。前面介紹概念的時(shí)候講過,處理信號(hào)有三種類型:進(jìn)程接收到信號(hào)后退出;進(jìn)程忽略該信號(hào);進(jìn)程收到信號(hào)后執(zhí)行用戶設(shè)定用系統(tǒng)調(diào)用signal的函數(shù)。當(dāng)進(jìn)程接收到一個(gè)它忽略的信號(hào)時(shí),進(jìn)程丟棄該信號(hào),就象沒有收到該信號(hào)似的繼續(xù)運(yùn)行。如果進(jìn)程收到一個(gè)要捕捉的信號(hào),那么進(jìn)程從內(nèi)核態(tài)返回用戶態(tài)時(shí)執(zhí)行用戶定義的函數(shù)。而且執(zhí)行用戶定義的函數(shù)的方法很巧妙,內(nèi)核是在用戶棧上創(chuàng)建一個(gè)新的層,該層中將返回地址的值設(shè)置成用戶定義的處理函數(shù)的地址,這樣進(jìn)程從內(nèi)核返回彈出棧頂時(shí)就返回到用戶定義的函數(shù)處,從函數(shù)返回再彈出棧頂時(shí),才返回原先進(jìn)入內(nèi)核的地方。這樣做的原因是用戶定義的處理函數(shù)不能且不允許在內(nèi)核態(tài)下執(zhí)行(如果用戶定義的函數(shù)在內(nèi)核態(tài)下運(yùn)行的話,用戶就可以獲得任何權(quán)限)。
在信號(hào)的處理方法中有幾點(diǎn)特別要引起注意。第一,在一些系統(tǒng)中,當(dāng)一個(gè)進(jìn)程處理完中斷信號(hào)返回用戶態(tài)之前,內(nèi)核清除用戶區(qū)中設(shè)定的對(duì)該信號(hào)的處理例程的地址,即下一次進(jìn)程對(duì)該信號(hào)的處理方法又改為默認(rèn)值,除非在下一次信號(hào)到來之前再次使用signal系統(tǒng)調(diào)用。這可能會(huì)使得進(jìn)程在調(diào)用signal之前又得到該信號(hào)而導(dǎo)致退出。在BSD中,內(nèi)核不再清除該地址。但不清除該地址可能使得
總結(jié)
以上是生活随笔為你收集整理的linux 信号(signal)介绍的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CString 字符串操作
- 下一篇: MySql加密存储的数据,如何模糊搜索?