linux操作系统之信号
(1)信號(hào)的概念
? ? ? ? ? ?信號(hào)的特點(diǎn):簡(jiǎn)單,不能攜帶大量信息,滿(mǎn)足某種特定條件才觸發(fā)。
? ? ? ? ? ?信號(hào)的機(jī)制;“軟中斷”,通過(guò)軟件方式實(shí)現(xiàn),具有很強(qiáng)的延時(shí)性。每個(gè)進(jìn)程收到的信號(hào),都由內(nèi)核負(fù)責(zé)發(fā)送,內(nèi)核處理。
? ? ? ? ? ?信號(hào)的產(chǎn)生:1)按鍵產(chǎn)生(ctrl+c,ctrl+z,ctrl+\)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?2) 系統(tǒng)調(diào)用產(chǎn)生(kill,abort,raise)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?3)軟件條件產(chǎn)生(定時(shí)器alarm)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?4)硬件異常產(chǎn)生((非法訪(fǎng)問(wèn)內(nèi)存)段錯(cuò)誤,(除0)浮點(diǎn)數(shù)例外,內(nèi)存對(duì)齊出錯(cuò)(總線(xiàn)錯(cuò)誤))
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?5)命令產(chǎn)生(kill)
? ? ? ? ?信號(hào)的處理方式:1)執(zhí)行默認(rèn)動(dòng)作
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 1>Term :終止進(jìn)程? 2>lgn:忽略信號(hào)3>core:終止進(jìn)程(查驗(yàn)死亡原因,gdb調(diào)試)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 4>Stop:停止(暫停)進(jìn)程5>Cont:繼續(xù)進(jìn)程
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?2)忽略(舍棄)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?3)捕捉(掉用戶(hù)處理函數(shù))
? ? ? ? ?信號(hào)的四要素:編號(hào)? 名稱(chēng)? 事件 默認(rèn)處理動(dòng)作
? ? ? ? Linux內(nèi)核中有一個(gè)PCB進(jìn)程控制塊,是一個(gè)結(jié)構(gòu)體,task_struct,里面保存了進(jìn)程id,狀態(tài),工作目錄,用戶(hù)id,用戶(hù)組id,文件描述符和阻塞信號(hào)集及未決信號(hào)集。
? ? ? ?信號(hào)的編號(hào):由kill -i查看當(dāng)前系統(tǒng)可使用的命令,其中1~31為常規(guī)信號(hào),34~64為實(shí)時(shí)信號(hào)。
? ? ? ?在31個(gè)常規(guī)信號(hào)中,9)SIGKILL和19)SIGSTOP信號(hào)不能被忽略和捕捉,智能執(zhí)行默認(rèn)動(dòng)作,不能設(shè)置其為阻塞。
(2)信號(hào)的產(chǎn)生
? ? ?1)終端按鍵產(chǎn)生信號(hào):ctrl+c? -->2)SIGINT(終止、中斷)ctrl+z --->20)SIGTSTP(暫時(shí)、停止)? ctrl+\--->3)SIGQUIT(退出)
? ? ?2) 硬件產(chǎn)生信號(hào):除零操作-->8)SIGFPE(浮點(diǎn)數(shù)例外)? ? ?非法訪(fǎng)問(wèn)內(nèi)存-->11)SIGSEGV(段錯(cuò)誤)? ?總線(xiàn)錯(cuò)誤 --->7)SIGBUS
? ? ?3)?kill函數(shù)或命令產(chǎn)生信號(hào): kill -SIGKILL pid
? ? ? ? ? ? ? int kill(pid_t pid,int sig);? ? ? 成功:0 失敗-1
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sig:不推薦直接使用數(shù)字,應(yīng)使用宏名。因?yàn)椴煌牟僮飨到y(tǒng)可能編號(hào)不一樣,但名稱(chēng)一致。
? ? ? ? ? ? ? ? pid>0? ?發(fā)送信號(hào)給指定進(jìn)程
? ? ? ? ? ? ? ? pid<0? ? 發(fā)送信號(hào)給調(diào)用kill函數(shù)同一進(jìn)程組的所有進(jìn)程。
? ? ? ? ? ? ? ?pid<0? ? ?取|pid|發(fā)給對(duì)應(yīng)進(jìn)程組
? ? ? ? ? ? ? ?pid=-1? ? 發(fā)送給當(dāng)前用戶(hù)組的所有進(jìn)程? ? ? ? ? ? ? ? ?
? ? ? ? ? ?raise函數(shù):給自己發(fā)指定信號(hào)? int raise(int sig)==kill(getpid(),sig)
? ? ? ? ? abort函數(shù):給自己發(fā)送異常終止信號(hào)? 6)SIGABRT信號(hào),終止并產(chǎn)生core文件,void abort(void)
? ? 4)軟件產(chǎn)生信號(hào)
? ? ? ? ? ? ?alarm函數(shù):定時(shí)固定秒數(shù)之后,內(nèi)核給當(dāng)前進(jìn)程發(fā)送14)SIGALRM信號(hào),終止進(jìn)程(每個(gè)進(jìn)程只有一個(gè)鬧鐘)? ?
? ? ? ? ? ? ?unsigned int alarm(unsigned int seconds);? 返回0或剩余的秒數(shù)(上一次定時(shí)剩余的秒數(shù))?alarm(0)取消定時(shí)
? ? ? ? ? ? ? ? ? ? ? ? 采用自然定時(shí)發(fā),與進(jìn)程狀態(tài)無(wú)關(guān)
? ? ? ? ? ? setitimer函數(shù):定時(shí)可以達(dá)到微秒,可實(shí)現(xiàn)循環(huán)定時(shí)。
? ? ? ? ? ? int setitimer(int which,const struct itimerval*new_value,struct itimerval*old_value);
? ? ? ? ? ? ? ? ? ? ?參數(shù)which(定時(shí)方式):ITIMER_REAL(自然定時(shí)法-)-->14)SIGLARM
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ITIMER_VIRTUAL(虛擬空間計(jì)時(shí),用戶(hù)時(shí)間)---->26)SIGVTALRM
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ITMER_PROF(運(yùn)行時(shí)間計(jì)時(shí),用戶(hù)+內(nèi)核)------>27)SIGPROF
? ? ? ? ? ? ? ? ? ?程序?qū)嶋H執(zhí)行的時(shí)間=系統(tǒng)時(shí)間+用戶(hù)時(shí)間+等待時(shí)間
? ? ? ? ? ? ? ? ??
? ? ? ? ? ? 其中it_interval為周期定時(shí)的時(shí)間,it_value為當(dāng)前定時(shí)的時(shí)間。
(3)信號(hào)集操作函數(shù)
? ? ? 內(nèi)核通過(guò)讀取未決信號(hào)集來(lái)判斷信號(hào)是否被處理,信號(hào)屏蔽字(阻塞信號(hào)集)mask可以影響未決信號(hào)集。? ? ? ? ? ??
? ? ? ? ? ?1 )信號(hào)集設(shè)定
? ? ? ? ? ? ? ?
? ? ? ? 2)sigprocmask函數(shù):屏蔽信號(hào),接觸屏蔽,設(shè)置信號(hào)集
? ? ? ? ? ? ?int sigprocmask(int how,const sigset_t*set,sigset_t*oldset);
? ? ? ? ? ? ? ? ? ? ? ? ? how:SIG_BLOCK,set表示需要屏蔽的信號(hào)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?SIG_UNBLOCK,set表示需要解屏蔽的信號(hào)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?SIG_SETMASK:set表示需要替代原始的新屏蔽集。
? ? ? ? 3)sigpending函數(shù):獲取當(dāng)前的未決信號(hào)集
? ? ? ? ? ? ? ? ? int sigpending(sigset_t*set);? ? //使用sigsimember來(lái)判斷某個(gè)信號(hào)是否在其中
(4)信號(hào)捕捉
? ? ? ? ? ?1)signal函數(shù):注冊(cè)一個(gè)信號(hào)捕捉函數(shù),抓信號(hào)由內(nèi)核進(jìn)行
? ? ? ? ? ? ? ? ? ? ? typedef void(*sighandler_t)(int);
? ? ? ? ? ? ? ? ? ? ?sighandler_t signal(int signum,sighandler_t handler);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?參數(shù):signum(捕捉的信號(hào))? handle(處理的函數(shù))
? ? ? ? ?2)sigaction函數(shù):修改信號(hào)處理動(dòng)作
? ? ? ? ? ? ? ? ? ? int sigaction(int signum,const struct sigaction*act,struct sigaction*oldact)
? ? ? ? ? ? ??
? ? ? ? ? ? ? 重點(diǎn)掌握:1>sa_handler:指定的信號(hào)捕捉后的處理函數(shù)名,可以賦值為SIG_IGN(表示忽略)SIG_DFL(表示執(zhí)行默認(rèn))
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 2>sa_mask:調(diào)用信號(hào)處理函數(shù)時(shí)使用的屏蔽信號(hào)集(臨時(shí)設(shè)置,執(zhí)行完函數(shù)即失效)(如果有信號(hào)為非屏蔽? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?信號(hào)集中的信號(hào),會(huì)先處理該信號(hào))
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?3>sa_flags:設(shè)置為0,表默認(rèn)屬性(信號(hào)捕捉函數(shù)期間,默認(rèn)屏蔽本信號(hào))
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?阻塞的常規(guī)信號(hào)不支持排隊(duì),產(chǎn)生多次只記錄一次,捕捉函數(shù)執(zhí)行完之后再執(zhí)行該阻塞信號(hào)。
? ? ? ? ? ? ?其他:第五個(gè)信號(hào)舍棄不用
? ? ? ? ? ? ? ? ? ? ? ? 當(dāng)sa_flags==SA_SIGINFO時(shí),使用第二個(gè)參數(shù)處理程序。
? ? ? ? ? ? 3)內(nèi)核實(shí)現(xiàn)信號(hào)捕獲過(guò)程
? ? ? ? ? ? ? ? ? ??
?
總結(jié)
以上是生活随笔為你收集整理的linux操作系统之信号的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: linux操作系统进程间通信IPC之共享
- 下一篇: linux操作系统信号捕捉函数之siga