信号捕捉

基础API

typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);	//  某些操作系统中行为可能不同

该函数由ANSI定义, 由于历史原因在不同版本的Unix和不同版本的Linux中可能有不同的行为. 因此应该尽量避免使用它, 取而代之使用sigaction函数

int sigaction(int signum, const struct, sigaction *act, struct sigaction *oldact);

struct sigaction {
   void     (*sa_handler)(int);			// 传入参数, 新的处理方式
   void     (*sa_sigaction)(int, siginfo_t *, void *);	// 一般不使用
   sigset_t   sa_mask;					// 在信号处理函数的执行过程中, 临时屏蔽指定的信号
   int        sa_flags;					// 使用sa_handler-->0
   void     (*sa_restorer)(void);		// 被废弃, 不再使用
};

重点掌握

  1. sa_handler: 指定信号捕捉后的处理函数名(即注册函数)。也可赋值为SIG_IGN表忽略或 SIG_DFL表执行默认动作
  2. sa_mask: 调用信号处理函数时,所要屏蔽的信号集合(信号屏蔽字)。注意:仅在处理函数被调用期间屏蔽生效,是临时性设置。
  3. sa_flags: 通常设置为0,表使用默认属性。

示例程序

signal

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <signal.h>

void myfunc(int nu) {
    printf("catch signal: %d", nu);
}

int main(int argc, const char *argv[]) {
    // 捕捉Ctrl + c
    signal(SIGINT, myfunc);

    while (1) {
        printf("haha\n");
        sleep(1);
    }

    return 0;
}

sigaction信号屏蔽

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <signal.h>

void myfunc(int nu) {
    printf("haha\n");
    sleep(3);
    printf("wake up\n");
}

int main(int argc, const char *argv[]) {
    struct sigaction act;
    act.sa_flags = 0;
    sigemptyset(&act.sa_mask);
    // 添加临时屏蔽信号, 临时屏蔽
    sigaddset(&act.sa_mask, SIGQUIT);
    act.sa_handler = myfunc;
    sigaction(SIGINT, &act, NULL);
    
    while (1) {}

    return 0;
}

/*多次发送信号只捕捉一个
^Chaha
wake up
^C^C^C^C^C^C^C^C^Chaha
wake up
^\^\^\^\Quit (core dumped)
*/
posted @ 2019-04-19 21:24  张飘扬  阅读(289)  评论(0编辑  收藏  举报