linux信號捕捉

信號捕捉,防止進程意外死亡

  1. signal函數
    man signal
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);

參數介紹;
signum 要捕捉的信號
handler 要執行的捕捉函數指針,函數聲明 void func(int)

  1. sigaction函數
    man sigaction
#include <signal.h>
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

參數介紹:
signum 要捕捉的信號

act 傳入的動作

struct sigaction {
    void     (*sa_handler)(int);//函數指針
    void     (*sa_sigaction)(int, siginfo_t *, void *);
    sigset_t   sa_mask;//執行捕捉函數期間,臨時屏蔽的信號集
    int        sa_flags; //一般用0(對應使用第一個函數指針),SA_SIGINFO會使用第二個函數指針
    void     (*sa_restorer)(void); //無效參數
};

oldact 傳出參數,原有的動作

代碼示例:
使用 sigaction 捕捉setitimer發出的 14號信號:

#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>
#include <signal.h>

void catch(int signum) {
    printf("catch sign num is %d\n", signum);
}
int main() {
    struct sigaction myact;
    myact.sa_handler = catch;
    sigemptyset(&(myact.sa_mask));
    myact.sa_flags = 0;
    sigaction(SIGALRM, &myact, NULL);
    struct itimerval itimer = {
        {3, 0},
        {2, 0}        
    };
    setitimer(ITIMER_REAL, &itimer, NULL);
    while (1) {
        printf("la la la\n");
        sleep(1);
    }
    
    return 0;
}
  1. 信號捕捉的特性
    ‘’’
    1.進程正常運行時,默認PCB中有一個信號屏蔽字,假定爲☆,它決定了進程自動屏蔽哪些信號。當註冊了某個信號捕捉函數,捕捉到該信號以後,要調用該函數。而該函數有可能執行很長時間,在這期間所屏蔽的信號不由☆來指定。而是用sa_mask來指定。調用完信號處理函數,再恢復爲☆。
    2.XXX信號捕捉函數執行期間,XXX信號自動被屏蔽。
    3.阻塞的常規信號不支持排隊,產生多次只記錄一次。(後32個實時信號支持排隊)
    ‘’’

  2. 內核實現信號捕捉過程
    在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章