更新時(shí)間:2020-12-25 17:36:03 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽1581次
信號(hào)(Signals)是Unix、類Unix以及其他POSIX兼容的操作系統(tǒng)中進(jìn)程間通訊的一種有限制的方式。Linux信號(hào)是Linux進(jìn)程間通信機(jī)制中唯一的異步通信機(jī)制,用來(lái)提醒進(jìn)程一個(gè)事件已經(jīng)發(fā)生。當(dāng)一個(gè)信號(hào)發(fā)送給一個(gè)進(jìn)程,操作系統(tǒng)中斷了進(jìn)程正常的控制流程,此時(shí),任何非原子操作都將被中斷。如果進(jìn)程定義了信號(hào)的處理函數(shù),那么它將被執(zhí)行,否則就執(zhí)行默認(rèn)的處理函數(shù)。
一般情況下,linux信號(hào)的來(lái)源可分為以下三種:
1.硬件方式:除數(shù)為零、無(wú)效的存儲(chǔ)訪問(wèn)等硬件異常產(chǎn)生信號(hào)。這些事件通常由硬件(如:CPU)檢測(cè)到,并將其通知給Linux操作系統(tǒng)內(nèi)核,然后內(nèi)核生成相應(yīng)的信號(hào),并把信號(hào)發(fā)送給該事件發(fā)生時(shí)正在進(jìn)行的程序。
2.軟件方式:用戶在終端下調(diào)用kill命令向進(jìn)程發(fā)送任務(wù)信號(hào)、進(jìn)程調(diào)用kill或sigqueue函數(shù)發(fā)送信號(hào)、當(dāng)檢測(cè)到某種軟件條件已經(jīng)具備時(shí)發(fā)出信號(hào),如由alarm或settimer設(shè)置的定時(shí)器超時(shí)時(shí)將生成SIGALRM信號(hào)等多種情景均可產(chǎn)生信號(hào)。
3.鍵盤輸入:當(dāng)用戶在終端上按下某鍵時(shí),將產(chǎn)生信號(hào)。如按下組合鍵Ctrl+C將產(chǎn)生一個(gè)SIGINT信號(hào),Ctrl+\產(chǎn)生一個(gè)SIGQUIT信號(hào)等。
我們可運(yùn)行kill -l查看Linux支持的信號(hào)列表:
sl@Li:~/Works$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
可以看到Linux中系統(tǒng)一共支持64種信號(hào),其中1到31號(hào)信號(hào)為普通信號(hào)(也程為不可靠信號(hào)),34到64為實(shí)時(shí)信號(hào)(可靠信號(hào))??煽啃盘?hào)與不可靠信號(hào)的區(qū)別:
這里的不可靠主要是不支持信號(hào)隊(duì)列,就是當(dāng)多個(gè)信號(hào)發(fā)生在進(jìn)程中的時(shí)候(收到信號(hào)的速度超過(guò)進(jìn)程處理的速度的時(shí)候),這些沒(méi)來(lái)的及處理的信號(hào)就會(huì)被丟掉,僅僅留下一個(gè)信號(hào)。
可靠信號(hào)是多個(gè)信號(hào)發(fā)送到進(jìn)程的時(shí)候(收到信號(hào)的速度超過(guò)進(jìn)程處理信號(hào)的速度的時(shí)候),這些沒(méi)來(lái)的及處理的信號(hào)就會(huì)排入進(jìn)程的隊(duì)列。等進(jìn)程有機(jī)會(huì)來(lái)處理的時(shí)候,依次再處理,信號(hào)不丟失。
下面列出幾個(gè)常用的信號(hào):
SIGHUP:
當(dāng)用戶退出終端時(shí),由該終端開啟的所有進(jìn)程都退接收到這個(gè)信號(hào),默認(rèn)動(dòng)作為終止進(jìn)程。
SIGINT:
程序終止(interrupt)信號(hào), 在用戶鍵入INTR字符(通常是Ctrl+C)時(shí)發(fā)出,用于通知前臺(tái)進(jìn)程組終止進(jìn)程。
SIGQUIT:
和SIGINT類似, 但由QUIT字符(通常是Ctrl+\)來(lái)控制. 進(jìn)程在因收到SIGQUIT退出時(shí)會(huì)產(chǎn)生core文件, 在這個(gè)意義上類似于一個(gè)程序錯(cuò)誤信號(hào)。
SIGKILL:
用來(lái)立即結(jié)束程序的運(yùn)行. 本信號(hào)不能被阻塞、處理和忽略。
SIGTERM:
程序結(jié)束(terminate)信號(hào), 與SIGKILL不同的是該信號(hào)可以被阻塞和處理。通常用來(lái)要求程序自己正常退出。
SIGSTOP:
停止(stopped)進(jìn)程的執(zhí)行. 注意它和terminate以及interrupt的區(qū)別:該進(jìn)程還未結(jié)束, 只是暫停執(zhí)行. 本信號(hào)不能被阻塞, 處理或忽略。
代碼示例:
下面的代碼收到程序退出信號(hào)后會(huì)執(zhí)行用戶定義的信號(hào)處理函數(shù)來(lái)替代系統(tǒng)默認(rèn)的處理程序。
#include<stdlib.h>
#include<stdio.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
void sig_handle(int sig) {
printf("received signal: %d, quit.\n", sig);
exit(0);
}
int main () {
signal(SIGINT, sig_handle);
signal(SIGKILL, sig_handle);
signal(SIGSEGV, sig_handle);
signal(SIGTERM, sig_handle);
int i = 0;
while (1) {
printf("%d\n", ++i);
sleep(2);
}
printf("main quit.");
return 0;
}
運(yùn)行結(jié)果:
received signal: 15, quit.
實(shí)際上,Linux信號(hào)可以看作是異步通知,通知接收信號(hào)的進(jìn)程有哪些事情發(fā)生了,也可以簡(jiǎn)單理解為信號(hào)是某種形式上的軟中斷。想要深入了解Linux信號(hào)的運(yùn)行機(jī)制,可以參考本站的Linux教程中給出的資料,結(jié)合自己在Linux系統(tǒng)上的實(shí)踐操作得出自己的結(jié)論。
Java實(shí)驗(yàn)班
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
Java就業(yè)班
有基礎(chǔ) 直達(dá)就業(yè)
Java夜校直播班
業(yè)余時(shí)間 高薪轉(zhuǎn)行
Java在職加薪班
工作1~3年,加薪神器
Java架構(gòu)師班
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問(wèn)老師會(huì)電話與您溝通安排學(xué)習(xí)