防偽碼:李白乘舟將欲行,忽聞岸上踏歌聲。
9.1 Linux 信號(hào)類(lèi)型
信號(hào)(Signal):信號(hào)是在軟件層次上對(duì)中斷機(jī)制的一種模擬,通過(guò)給一個(gè)進(jìn)程發(fā)送信號(hào),執(zhí)行響
應(yīng)的處理函數(shù)。
進(jìn)程可以通過(guò)三種方式來(lái)響應(yīng)一個(gè)信號(hào):
1)忽略信號(hào),即對(duì)信號(hào)不做任何處理,其中有兩個(gè)信號(hào)不能忽略:SIGKILL 及 SIGSTOP。
2)捕捉信號(hào)。
3)執(zhí)行缺省操作,Linux 對(duì)每種信號(hào)都規(guī)定了默認(rèn)操作。
Linux 究竟采用上述三種方式的哪一個(gè)來(lái)響應(yīng)信號(hào)呢?取決于傳遞給響應(yīng) API 函數(shù)的參數(shù)。
Linux 支持的信號(hào)有:
編號(hào) 信號(hào)名稱(chēng) 缺省動(dòng)作 描述
1 SIGHUP 終止 終止進(jìn)程,掛起
2 SIGINT 終止 鍵盤(pán)輸入中斷命令,一般是 CTRL+C
3 SIGQUIT CoreDump 鍵盤(pán)輸入退出命令,一般是 CTRL+\
4 SIGILL CoreDump 非法指令
5 SIGTRAP CoreDump trap 指令發(fā)出,一般調(diào)試用
6 SIGABRT CoreDump abort(3)發(fā)出的終止信號(hào)
7 SIGBUS CoreDump 非法地址
8 SIGFPE CoreDump 浮點(diǎn)數(shù)異常
9 SIGKILL 終止 立即停止進(jìn)程,不能捕獲,不能忽略
10 SIGUSR1 終止
用戶(hù)自定義信號(hào) 1,像 Nginx 就支持 USR1 信號(hào),用于重載配
置,重新打開(kāi)日志
11 SIGSEGV CoreDump 無(wú)效內(nèi)存引用
12 SIGUSR2 終止 用戶(hù)自定義信號(hào) 2
13 SIGPIPE 終止 管道不能訪(fǎng)問(wèn)
14 SIGALRM 終止 時(shí)鐘信號(hào),alrm(2)發(fā)出的終止信號(hào)
15 SIGTERM 終止
終止信號(hào),進(jìn)程會(huì)先關(guān)閉正在運(yùn)行的任務(wù)或打開(kāi)的文件再終
止,有時(shí)間進(jìn)程在有運(yùn)行的任務(wù)而忽略此信號(hào)。不能捕捉
16 SIGSTKFLT 終止 處理器棧錯(cuò)誤
17 SIGCHLD 可忽略 子進(jìn)程結(jié)束時(shí),父進(jìn)程收到的信號(hào)
18 SIGCONT 可忽略 讓終止的進(jìn)程繼續(xù)執(zhí)行
19 SIGSTOP 停止 停止進(jìn)程,不能忽略,不能捕獲
20 SIGSTP 停止 停止進(jìn)程,一般是 CTRL+Z
21 SIGTTIN 停止 后臺(tái)進(jìn)程從終端讀數(shù)據(jù)
22 SIGTTOU 停止 后臺(tái)進(jìn)程從終端寫(xiě)數(shù)據(jù)
23 SIGURG 可忽略 緊急數(shù)組是否到達(dá) socket
24 SIGXCPU CoreDump 超出 CPU 占用資源限制
25 SIGXFSZ CoreDump 超出文件大小資源限制
26 SIGVTALRM 終止
虛擬時(shí)鐘信號(hào),類(lèi)似于 SIGALRM,但計(jì)算的是進(jìn)程占用的時(shí)
間
27 SIGPROF 終止 類(lèi)似與 SIGALRM,但計(jì)算的是進(jìn)程占用 CPU 的時(shí)間
28 SIGWINCH 可忽略 窗口大小改變發(fā)出的信號(hào)
29 SIGIO 終止 文件描述符準(zhǔn)備就緒,可以輸入/輸出操作了
30 SIGPWR 終止 電源失敗
31 SIGSYS CoreDump 非法系統(tǒng)調(diào)用
CoreDump(核心轉(zhuǎn)儲(chǔ)):當(dāng)程序運(yùn)行過(guò)程中異常退出時(shí),內(nèi)核把當(dāng)前程序在內(nèi)存狀況存儲(chǔ)在一個(gè)
core 文件中,以便調(diào)試。
Linux 支持兩種信號(hào):
一種是標(biāo)準(zhǔn)信號(hào),編號(hào) 1-31,稱(chēng)為非可靠信號(hào)(非實(shí)時(shí)),不支持隊(duì)列,信號(hào)可能會(huì)丟失,比如發(fā)
送多次相同的信號(hào),進(jìn)程只能收到一次,如果第一個(gè)信號(hào)沒(méi)有處理完,第二個(gè)信號(hào)將會(huì)丟棄。
另一種是擴(kuò)展信號(hào),編號(hào) 32-64,稱(chēng)為非可靠信號(hào)(實(shí)時(shí)),支持隊(duì)列,發(fā)多少次進(jìn)程就可以收到
多少次。
信號(hào)類(lèi)型比較多,我們只要了解下,記住幾個(gè)常用信號(hào)就行了,紅色標(biāo)記的我覺(jué)得需要記下。
發(fā)送信號(hào)一般有兩種情況:
一種是內(nèi)核檢測(cè)到系統(tǒng)事件,比如鍵盤(pán)輸入 CTRL+C 會(huì)發(fā)送 SIGINT 信號(hào)。
另一種是通過(guò)系統(tǒng)調(diào)用 kill 命令來(lái)向一個(gè)進(jìn)程發(fā)送信號(hào)。
l 9.2 kill 命令
kill 命令發(fā)送信號(hào)給進(jìn)程。
命令格式:kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l
[sigspec]
-s # 信號(hào)名稱(chēng)
-n # 信號(hào)編號(hào)
-l # 打印編號(hào) 1-31 信號(hào)名稱(chēng)
示例:
給一個(gè)進(jìn)程發(fā)送終止信號(hào):
kill -s SIGTERM pid
或
kill -n 15 pid
或
kill -15 pid
或
kill -TREM pid
p 9.3 trap 命令
trap 命令定義 shell 在處理程序運(yùn)行時(shí)接受信號(hào),來(lái)做相應(yīng)的處理。
命令格式:trap [-lp] [[arg] signal_spec ...]
-l # 打印編號(hào) 1-64 編號(hào)信號(hào)名稱(chēng)
arg # 捕獲信號(hào)后執(zhí)行的命令或者函數(shù)
signal_spec # 信號(hào)名或編號(hào)
一般捕捉信號(hào)后,做以下幾個(gè)行動(dòng):
1)清除臨時(shí)文件
2)忽略該信號(hào)
3)詢(xún)問(wèn)用戶(hù)是否終止腳本執(zhí)行
示例 1:按 CTRL+C 不退出循環(huán)
#!/bin/bash
trap "" 2 # 不指定 arg 就不做任何操作,后面也可以寫(xiě)多個(gè)信號(hào),以空格分隔
for i in {1..10}; do
echo $i
sleep 1
done
# bash a.sh
1
2
3
^C4
5
6
^C7
8
9
10
示例 2:循環(huán)打印數(shù)字,按 CTRL+C 退出,并打印退出提示
#!/bin/bash
trap "echo 'exit...';exit" 2
for i in {1..10}; do
echo $i
sleep 1
done
# bash test.sh
1
2
3
^Cexit...
示例 3:讓用戶(hù)選擇是否終止循環(huán)
#!/bin/bash
trap "func" 2
func() {
read -p "Terminate the process? (Y/N): " input
if [ $input == "Y" ]; then
exit
fi
}
for i in {1..10}; do
echo $i
sleep 1
done
# bash a.sh
1
2
3
^CTerminate the process? (Y/N): Y
# bash a.sh
1
2
3
^CTerminate the process? (Y/N): N
4
5
6
...
謝謝觀看,真心的希望能幫到您!
本文出自 “一盞燭光” 博客,謝絕轉(zhuǎn)載!
更多建議: