- 相關(guān)推薦
Linux下C編程:信號處置方法實(shí)習運用
Linux下C編程:信號處置方法實(shí)習運用
信號是用于一步作業(yè)的。當一個(gè)信號發(fā)生時(shí),程序會(huì )按照現已設定好的程序來(lái)實(shí)行相應的操作。
進(jìn)程對信號處置的方法通常有兩種:
1、捕捉信號:當一個(gè)信號發(fā)送個(gè)進(jìn)程時(shí),該進(jìn)程會(huì )調用此信號注冊的信號處置函數,來(lái)結束相應的操作。對應于每個(gè)信號系統通常會(huì )有相應的默許處置函數(通常為間斷進(jìn)程)。所以可以設置信號為默許的處置函數。
2、忽略信號。當信號發(fā)送時(shí),進(jìn)程忽略信號。
注:有兩個(gè)信號是無(wú)法捕捉和忽略的SIGKILL和SIGSTOP。它們是提供給管理員,可以在任何時(shí)辰間斷某個(gè)進(jìn)程而設定的。
對信號處置的需要:在用戶(hù)編程時(shí)有時(shí)進(jìn)程需要對某信號進(jìn)行當即照應。對有些實(shí)時(shí)進(jìn)程來(lái)說(shuō),當它實(shí)行時(shí)是不愿意被打斷的,這是就需要把接收的信號掛起。
信號的運用:
信號最常見(jiàn)的一個(gè)運用便是發(fā)生差錯時(shí)通知進(jìn)程結束。關(guān)于許多差錯,如bus差錯,浮點(diǎn)差錯,調用內存差錯等都有相應的信號通知進(jìn)程。
此外信號還有其他用途。如作業(yè)一個(gè)大型的科學(xué)運算程序,如果在一個(gè)無(wú)量循環(huán)頂用printf來(lái)閃現作業(yè)情況,必定構成作業(yè)功率的下降。所以通過(guò)信號,人為的向進(jìn)程發(fā)送消息,來(lái)查看作業(yè)情況,就大大的提高了作業(yè)功率。
Linux下C編程:信號具體含義說(shuō)明
信號及其簡(jiǎn)介
信號是一種進(jìn)程通訊的方法,他運用于異步作業(yè)的處置。信號的結束是一種軟間斷。它被發(fā)送為一個(gè)正在作業(yè)的進(jìn)程,已奉告進(jìn)程某個(gè)作業(yè)發(fā)生了。
1) SIGHUP本信號在用戶(hù)終端聯(lián)接(正;蚍钦)結束時(shí)宣告,通常是在終端的控制進(jìn)程結束時(shí),通知同一session內的各個(gè)作業(yè),這時(shí)它們與控制終端不再有關(guān).
2) SIGINT程序間斷(interrupt)信號,通常是從終端宣告間斷指令如ctrl+c或鍵
3) SIGQUIT和SIGINT類(lèi)似,但由QUIT字符(通常是Ctrl+\)來(lái)控制.進(jìn)程在因收到SIGQUIT退出時(shí)會(huì )發(fā)生core文件,在這個(gè)含義上類(lèi)似于一個(gè)程序差錯信號.
4) SIGILL實(shí)行了不合法指令.通常是因為可實(shí)行文件本身出現差錯,或許妄圖實(shí)行數據段.庫房溢出時(shí)也有可以發(fā)生這個(gè)信號.
5) SIGTRAP跟蹤騙局信號,由斷點(diǎn)指令或其它trap指令發(fā)生.由debugger運用.
6) SIGABRT調用abort時(shí)發(fā)生的信號,將會(huì )使進(jìn)程非正常結束。
6) SIGIOT IO差錯信號.
7) SIGBUS系統總線(xiàn)差錯時(shí)發(fā)生的信號,不合法地址,包括內存地址對齊(alignment)犯錯.eg:訪(fǎng)問(wèn)一個(gè)四個(gè)字長(cháng)的整數,但其地址不是4的倍數.
8) SIGFPE在發(fā)生喪身的算術(shù)運算差錯時(shí)宣告.不只包括浮點(diǎn)運算差錯,還包括溢出及除數為0等其它一切的算術(shù)的差錯.
9) SIGKILL可以間斷任何進(jìn)程的信號,只能由管理員宣告,該信號不會(huì )被捕捉和忽略。
10) SIGUSR1留給用戶(hù)運用,用戶(hù)可在運用程序中自行定義。
11) SIGSEGV妄圖訪(fǎng)問(wèn)未分配給自個(gè)的內存,或妄圖往沒(méi)有寫(xiě)權限的內存地址寫(xiě)數據,不合法運用內存地址信號。
12) SIGUSR2留給用戶(hù)運用
13) SIGPIPE當一個(gè)進(jìn)程對管道進(jìn)行完讀后進(jìn)行寫(xiě)時(shí)發(fā)生的信號。
14) SIGALRM時(shí)鐘守時(shí)信號,由alarm函數設定的時(shí)辰間斷時(shí)發(fā)生的信號。
15) SIGTERM程序結束(terminate)信號,與SIGKILL不一樣的是該信號可以被阻塞和處置.通常用來(lái)需要程序自個(gè)正常退出.shell指令kill缺省發(fā)生這個(gè)信號.
17) SIGCHLD子進(jìn)程結束或間斷時(shí)發(fā)生該信號,父進(jìn)程會(huì )收到這個(gè)信號.通過(guò)該信號父進(jìn)程可以知道子進(jìn)程的作業(yè)情況。但大多數情況下此信號會(huì )被忽略。
18) SIGCONT讓一個(gè)間斷(stopped)的進(jìn)程繼續實(shí)行.本信號不能被阻塞.
19) SIGSTOP間斷(stopped)進(jìn)程的實(shí)行.注意它和terminate以及interrupt的區別:該進(jìn)程還未結束,只是暫停實(shí)行.本信號不能被阻塞,處置或忽略.
20) SIGTSTP間斷進(jìn)程的作業(yè),但該信號可以被處置和忽略.用戶(hù)鍵入SUSP字符時(shí)(通常是Ctrl-Z)宣告這個(gè)信號
21) SIGTTIN當后臺作業(yè)要從用戶(hù)終端讀數據時(shí),間斷驅動(dòng)器發(fā)生的信號。當讀入數據的進(jìn)程阻塞或忽略這個(gè)信號,或讀取數據的進(jìn)程地址進(jìn)程組是一個(gè)孤立進(jìn)程組時(shí),信號不會(huì )發(fā)生,而且發(fā)生讀差錯。errno被設為ETO
22) SIGTTOU類(lèi)似于SIGTTIN,當后臺作業(yè)要從用戶(hù)終端讀數據時(shí),間斷驅動(dòng)器發(fā)生的信號。當讀入數據的進(jìn)程阻塞或忽略這個(gè)信號,或讀取數據的進(jìn)程地址進(jìn)程組是一個(gè)孤立進(jìn)程組時(shí),信號不會(huì )發(fā)生,而且發(fā)生讀差錯。errno被設為ETO。僅有不一樣的是進(jìn)程可以選擇后臺寫(xiě)。
23) SIGURG socket上出現緊急情況是宣告的信息。
24) SIGXCPU逾越CPU時(shí)辰資源束縛.這個(gè)束縛可以由getrlimit/setrlimit來(lái)讀取/改動(dòng)
25) SIGXFSZ逾越文件大小資源束縛.
26) SIGVTALRM虛擬時(shí)鐘信號.類(lèi)似于SIGALRM,可是核算的是該進(jìn)程占用的CPU時(shí)辰.
27) SIGPROF類(lèi)似于SIGALRM/SIGVTALRM,但包括該進(jìn)程用的CPU時(shí)辰以及系統調用的時(shí)辰.
28) SIGWINCH窗口大小改動(dòng)時(shí)宣告.
29) SIGIO文件描述符準備就緒,可以初步進(jìn)行輸入/輸出操作.
30) SIGPWR Power failure電源失效信號。
31)SIGEMT實(shí)時(shí)硬件發(fā)生差錯時(shí)發(fā)生的信號。
有兩個(gè)信號可以間斷進(jìn)程:SIGTERM和SIGKILL。SIGTERM比照和睦,進(jìn)程能捕捉這個(gè)信號,根據您的需要來(lái)關(guān)閉程序。在關(guān)閉程序之前,您可以結束翻開(kāi)的記載文件和結束正在做的任務(wù)。在某些情況下,假定進(jìn)程正在進(jìn)行作業(yè)而且不能間斷,那么進(jìn)程可以忽略這個(gè)SIGTERM信號。
關(guān)于SIGKILL信號,進(jìn)程是不能忽略的。這是一個(gè)“我不管您在做什么,立刻間斷”的信號。假定您發(fā)送SIGKILL信號給進(jìn)程,Linux就將進(jìn)程間斷在那里。
注:有六個(gè)信號被稱(chēng)為作業(yè)信號,SIGCHLD,SIGCONT,SIGSTOP,SIGSTP,SIGTTNI,SIGTTOU.這些信號都是用于協(xié)和諧組織各個(gè)進(jìn)程的,也便是結束所謂的作業(yè)控制。通常情況下用戶(hù)不需要對這些信號進(jìn)行處置,shell會(huì )自動(dòng)結束對這些信號的處置作業(yè)。信號之間是相互影響的,當進(jìn)程接收到SIGCONT信號時(shí),被系統懸掛的SIGSTOP,SIGSTP,SIGTTIN,SIGTTOU將失效。一樣進(jìn)程接收到SIGSTOP,SIGSTP,SIGTTIN,SIGTTOU時(shí),SIGCONT將失效。
Linux下C編程:信號處置
信號處置是linux程序的一個(gè)特征。用信號處置來(lái)仿照操作系統的間斷功用。要想運用信號處置功用,你要做的便是填寫(xiě)一個(gè)信號處置函數即可。
#include
#include
#include
#include
int flag = 1;
void func(int sig)
{
printf("I get a signal!\n");
flag = 0;
}
int main()
{
signal(SIGINT, func);
printf("pid:%ld\n",(long)getpid());
while(flag)
pause();
return 0;
}實(shí)行,
#gcc sig.c -o sig
#./sig
在另一終端:
#kill -INT 333//333是程序打印出的進(jìn)程號