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