訊號捕捉 、pause函式和SIGCHLD訊號
阿新 • • 發佈:2019-01-09
一、訊號捕捉
訊號捕捉針對於自定義的函式處理訊號方式。訊號遞達呼叫這個函式稱為捕捉訊號。發生訊號並不是立即處理的,而是找合適的機會,這個機會就是從核心態切換到使用者態的時候處理訊號。
使用者態切換到核心態的方式:(1)系統呼叫(2)程式異常(3)軟體中斷
訊號捕捉流程順序見下圖:
二、pause函式
呼叫pause函式回事程序掛起,直到有訊號遞達。如果訊號的處理動作是終止程序,則程序終止,pause函式沒有機會返回。
如果訊號的處理動作是忽略的,則程序繼續處於掛起狀態,pause不返回。如果訊號的處理動作為捕捉,則呼叫處理函式之後pause函式返回-1,error設定為EINTR,所以pause只有出錯返回值,沒有成功返回值和我們之前講過的程式替換函式一樣。
三、SIGCHLD訊號
我們之前涉及到的殭屍程序,是由於子程序先於父程序退出,父程序沒有關心子程序的退出狀態導致殭屍程序。其實子程序退出會給父程序傳送一個訊號就是SIGCHLD。之前避免殭屍程序一種方法就是阻塞式的等待,父程序就不能處理自己的工作。第二種就是waitpid輪詢等待的方式,但是這種父程序一邊要處理自己的工作,另外一邊還要輪詢查詢子程序是否結束,這樣程式實現起來比較複雜。
我們可以使用該訊號來處理殭屍程序,通過對該訊號的自定義處理函式,然後父程序只管處理自己的事情,如果該訊號到來父程序去處理,處理完畢之後接著做父程序的事情。
#include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<signal.h> #include<sys/wait.h> void sigcb(int signo) { while(waitpid(-1,0,WNOHANG)>0) { printf("signo:%d\n",signo); } } int main() { signal(SIGCHLD,sigcb); int pid = fork(); if(pid<0) { perror("fork error"); exit(1); } else if(pid == 0) { sleep(5); exit(1); } else { while(1) { printf("waiting!!!\n"); sleep(1); } } return 0; }