信号捕捉
基础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); // 被废弃, 不再使用
};
重点掌握
- sa_handler: 指定信号捕捉后的处理函数名(即注册函数)。也可赋值为SIG_IGN表忽略或 SIG_DFL表执行默认动作
- sa_mask: 调用信号处理函数时,所要屏蔽的信号集合(信号屏蔽字)。注意:仅在处理函数被调用期间屏蔽生效,是临时性设置。
- 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)
*/