signal.h是C标准函数库中的信号处理部分,定义了程序执行时如何处理不同的信号。信号用作进程间通信,报告异常行为(如除零)、用户的一些按键组合(如同时按下Ctrl与C键,产生信号SIGINT)。C++中的对应头文件是csignal。
C语言标准定义了6个信号,都定义在signal.h头文件中:
(1). SIGABRT:程序异常中止,如调用abort函数。
(2). SIGFPE:算术运算出错,如除数为0或溢出。
(3). SIGILL:非法函数映像,如非法指令。
(4). SIGINT:交互的用户按键请求,如同时按下Ctrl+C键。
(5). SIGSEGV:无效内存访问,段错误。
(6). SIGTERM:程序的中止请求。
signal.h可能还定义了其它信号,这依赖于具体实现。例如,类Unix系统还定义了15个以上的信号。Visual C++的C标准库只支持C语言标准规定的6个信号,即对信号处理只提供最小的支持。
signal函数:该函数设置一个函数(回调函数)来处理捕获到异常信号时需要执行的操作,其函数声明方式如下:
// Type of a signal handler
typedef void (*__sighandler_t)(int);
__sighandler_t signal(int __sig, __sighandler_t __handler);
测试代码:
#include <signal.h>
#include <string>
#include <thread>
#include <chrono>bool flag = true;void process_exit(int sig)
{switch (sig) {case SIGINT:fprintf(stderr, "process exit: SIGINT: value: %d\n", sig);break;case SIGFPE:fprintf(stderr, "process exit: SIGFPE: value: %d\n", sig);break;case SIGABRT:fprintf(stderr, "process exit: SIGABRT: value: %d\n", sig);break;case SIGILL:fprintf(stderr, "process exit: SIGILL: value: %d\n", sig);break;case SIGSEGV:fprintf(stderr, "process exit: SIGSEGV: value: %d\n", sig);break;case SIGTERM:fprintf(stderr, "process exit: SIGTERM: value: %d\n", sig);break;default:fprintf(stderr, "process exit: value: %d\n", sig);break;}flag = false;
}void wait_ctrl_c()
{while (flag) {std::this_thread::sleep_for(std::chrono::seconds(2));fprintf(stdout, "please press to exit: Ctrl + c ... \n");}
}void signal_type()
{signal(SIGINT, process_exit);signal(SIGFPE, process_exit);signal(SIGILL, process_exit);signal(SIGABRT, process_exit);signal(SIGSEGV, process_exit);signal(SIGTERM, process_exit);
}void signal_sigill(int)
{fprintf(stdout, "caught SIGILL signal\n");
}void signal_sigterm(int)
{fprintf(stdout, "caught SIGTERM signal\n");
}int test_signal_SIGINT()
{signal_type();std::thread th(wait_ctrl_c);th.join();return 0;
}int test_signal_SIGILL()
{//signal_type();if (signal(SIGILL, signal_sigill) == SIG_ERR) {fprintf(stdout, "cannot handle SIGILL\n");} else {fprintf(stdout, "yyyyy\n");}return 0;
}int test_signal_SIGFPE()
{signal_type();int a = 1, b = 0, c;c = a / b;fprintf(stdout, "c = %d\n", c);return 0;
}int test_signal_SIGSEGV()
{signal_type();int a[3] = {0};fprintf(stdout, "a[3] = %d\n", a[-1111111]);return 0;
}int test_signal_SIGTERM()
{//signal_type();if (signal(SIGTERM, signal_sigterm) == SIG_ERR) {fprintf(stdout, "cannot handle SIGTERM\n");} else {fprintf(stdout, "xxxxx\n");}return 0;
}int test_signal_SIGABRT()
{signal_type();abort();return 0;
}int main(){
// test_signal_SIGABRT();
// test_signal_SIGFPE();
// test_signal_SIGILL();
// test_signal_SIGINT();
// test_signal_SIGSEGV();test_signal_SIGTERM();return 0;
}