信号是由操作系统,可以提早终止一个程序传送到一个过程中的中断。可以通过按Ctrl+C在UNIX,LINUX,Mac OS X或Windows系统上产生中断。
不能捕获程序的信号,但存在着而可以在程序中捕捉并可以采取基于信号适当的动作的信号如下面的列表。这些信号在C++头文件<csignal>定义。
信号 | 描述 |
---|---|
SIGABRT | 异常终止程序,如调用abort |
SIGFPE | 错误的算术运算,例如除零或导致溢出的操作 |
SIGILL | 检测非法指令 |
SIGINT | 接收到交互注意信号 |
SIGSEGV | 一个非法访问存储 |
SIGTERM | 发送到程序的终止请求 |
signal() 函数:
C++信号处理库提供函数来捕获信号突发事件。以下是signal()函数的语法:
void (*signal (int sig, void (*func)(int)))(int);
保持简单,这个函数接收两个参数:第一个参数是一个整数,代表信号的号;第二个参数是一个指向信号处理函数。
让我们写一个简单的C++程序,使用signal()函数捕获到SIGINT信号。不管信号在程序中捕获,必须使用信号函数来注册的信号,并将其与信号处理程序相关联。看看下面的例子:
#include <iostream> #include <csignal> using namespace std; void signalHandler( int signum ) { cout << "Interrupt signal (" << signum << ") received. "; // cleanup and close up stuff here // terminate program exit(signum); } int main () { // register signal SIGINT and signal handler signal(SIGINT, signalHandler); while(1){ cout << "Going to sleep...." << endl; sleep(1); } return 0; }
让我们编译和运行上面的程序,这将产生以下结果:
Going to sleep.... Going to sleep.... Going to sleep....
现在,按Ctrl+ C来中断程序,会看到程序捕获的信号,并退出来打印的内容如下:
Going to sleep.... Going to sleep.... Going to sleep.... Interrupt signal (2) received.
raise() 函数:
可以生成由函数raise(),这需要一个整数信号编号作为参数,信号语法如下。
int raise (signal sig);
在这里,SIG是发送任何信号的信号编号:SIGINT,SIGABRT,SIGFPE,SIGILL,SIGSEGV,SIGTERM,SIGHUP。以下是我们引发一个信号内部使用raise()函数的例子,如下:
#include <iostream> #include <csignal> using namespace std; void signalHandler( int signum ) { cout << "Interrupt signal (" << signum << ") received. "; // cleanup and close up stuff here // terminate program exit(signum); } int main () { int i = 0; // register signal SIGINT and signal handler signal(SIGINT, signalHandler); while(++i){ cout << "Going to sleep...." << endl; if( i == 3 ){ raise( SIGINT); } sleep(1); } return 0; }
当上面的代码被编译和执行,这将产生以下结果,并会自动出来:
Going to sleep.... Going to sleep.... Going to sleep.... Interrupt signal (2) received.