signal()是ANSI C信号处理函数,原型如下:
#include <signal.h>typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
signal()将信号signum的处置设置为handler,该handler为SIG_IGN(忽略), SIG_DFL(默认),或者是自定义函数的地址。
可以处理的一些信号:
信号名称 值 描述
SIGINT 2 Interrupt (ANSI) 中断;e.g.终端键入DELETE或ctrl+c按键
SIGILL 4 Illegal instruction (ANSI) 非法指令
SIGABRT 6 Abort (ANSI) abort()异常终止
SIGBUS 7 BUS error (4.2 BSD) 硬件故障
SIGFPE 8 Floating-point exception (ANSI) 浮点异常
SIGSEGV 11 Segmentation violation (ANSI) 段错误
SIGPIPE 13 Broken pipe (POSIX) 管道破裂
SIGTERM 15 Termination (ANSI) 尽可能终止
SIGSTKFLT 16 Stack fault 栈异常,默认终止进程
SIGCHLD 17 Child status has changed (POSIX) 子进程状态改变
注意:信号SIGKILL和SIGSTOP不能被捕获或忽略。
程序示例:
#include <stdio.h>
#include <unistd.h>
#include <signal.h>void signal_handler(int sig_no)
{printf("handling signal: %d\n", sig_no);
}int main(int argc, char *argv[])
{signal(SIGINT , signal_handler);signal(SIGILL , signal_handler);signal(SIGABRT , signal_handler);signal(SIGBUS , signal_handler);signal(SIGFPE , signal_handler);signal(SIGSEGV , signal_handler);signal(SIGTERM , signal_handler);signal(SIGSTKFLT, signal_handler);signal(SIGPIPE , SIG_IGN);signal(SIGCHLD , SIG_IGN);while(1){sleep(1);}return 0;
}
编译运行程序,开启另一个终端,键入ps命令查看运行程序的PID,键入kill命令给该进程发送不同的信号,示例如下图:
从上面图片中可以看到,SIGSEGV和SIGILL信号被程序捕获然后输出打印信号值,SIGPIPE信号被程序忽略,SIGKILL信号不能被捕获,程序被无条件终止。都符合程序预期。
如果不希望程序遇到段错误等情况就被终止,可以自定义handler函数,捕获相关信号,必要时保存堆栈信息,便于后续定位分析问题。