函數sigaction

函數sigaction、signal

struct sigaction 結構體

struct sigaction
{
    void(*sa_handler)(int);//不帶附加參數的信號處理函數指針
    void(*sa_sigaction)(int, siginfo_t *, void *);//帶有附加參數的信號處理函數指針(兩個信號處理函數指針只能二選一)
    sigset_t sa_mask;//在執行信號處理函數時,應該屏蔽掉哪些信號
    int sa_flags;//用於控制信號行爲,它的值可以是下面選項的組合
    //SA_SIGINFO:如果指定該選項,則向信號處理函數傳遞參數(這時應該使用 sa_sigaction 成員而不是 sa_handler).
    void(*sa_restorer)(void);//該成員在早期是用來清理函數棧的,如今已被廢棄不用。
};

函數sigaction原型

/*
參數 signum :要捕獲的信號。
參數act:truct sigaction 結構體,後面具體講解傳入參數,新的處理方式
參數oldact:返回舊的 struct sigaction 結構體,傳出參數,舊的處理方式
*/
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

測試代碼

#include <unistd.h>
#include <signal.h>
#include <stdio.h>
void printsigset(const sigset_t *set)
{
    for (int i = 1; i <= 64; i++)  {
        if (i == 33) putchar(' ');
        if (sigismember(set, i) == 1)
            putchar('1');
        else
            putchar('0');
    }
    puts("");
}
void handler(int sig)
{
    if (sig == SIGTSTP)
        printf("hello SIGTSTP\n");
    if (sig == SIGINT)
        printf("hello SIGINT\n");
    sleep(5);
    sigset_t st;
    sigpending(&st);
    printsigset(&st);
}
int main()
{
    printf("I'm %d\n", getpid());
    struct sigaction act, oldact;
    act.sa_handler = handler;   // 設置普通信號處理函數
    sigemptyset(&act.sa_mask);  // 向 sa_mask 中添加 SIGINT
    sigaddset(&act.sa_mask, SIGINT);
    act.sa_flags = 0; // 先置 0
    sigaction(SIGTSTP, &act, &oldact);
    sigaction(SIGINT, &act, &oldact);
    while (1)  {
        write(STDOUT_FILENO, ".", 1);
        pause();
    }
    return 0;
}
/*
1、當程序運行的時候,Ctrl C 進入 handler,然後立即 Ctrl Z 發現 handler 還未執行完就被 SIGTSTP 打斷。
2、當程序運行的時候,Ctrl Z 進入 handler,然後立即 Ctrl C 發現並不會被 SIGINT 打斷,這是因爲該 handler 
註冊的時候被設置了 SA_MASK = SIGINT。最後 handler 結束的時候打印了未決信號集,發現裏頭有 SIGINT。
所以 handler 結束後,又去繼續對 SIGINT 進行處理。
*/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章