函数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 进行处理。
*/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章