信号量是由操作系统发送给进程的中断信号,它可以提前终止程序。你可以在 UNIX、LINUX、Mac OS X 或 Windows 系统上通过按下 Ctrl+C 来生成中断。
有一些信号不能被程序捕获,但以下列表中列出了你可以捕获并在程序中根据信号采取适当行动的信号。这些信号定义在 C++ 标头文件 <csignal>
中。
序号 |
信号 |
描述 |
1 |
SIGABRT |
程序异常终止,例如调用了 abort 。 |
2 |
SIGFPE |
发生错误的算术运算,例如除以零或导致溢出的操作。 |
3 |
SIGILL |
发现非法指令。 |
4 |
SIGINT |
收到交互式注意信号。 |
5 |
SIGSEGV |
存储访问无效。 |
6 |
SIGTERM |
发送给程序的终止请求。 |
signal() 函数
C++ 信号处理库提供了 signal
函数来捕获意外事件。signal()
函数的语法如下:
void (*signal (int sig, void (*func)(int)))(int);
简单来说,这个函数接收两个参数:第一个参数是一个代表信号编号的整数,第二个参数是一个指向信号处理函数的指针。
让我们写一个简单的 C++ 程序,其中我们将使用 signal()
函数来捕获 SIGINT 信号。无论你在程序中想要捕获哪个信号,你都必须使用 signal
函数注册该信号,并将其与一个信号处理程序关联起来。请参阅以下示例:
#include <iostream>
#include <csignal>
using namespace std;
void signalHandler( int signum ) {
cout << "接收到中断信号 (" << signum << ").\n";
exit(signum);
}
int main () {
signal(SIGINT, signalHandler);
while(1) {
cout << "正在休眠...\n";
sleep(1);
}
return 0;
}
当上述代码被编译和执行时,会产生如下结果:
正在休眠...
正在休眠...
正在休眠...
现在,按下 Ctrl+c 来中断程序,你会看到你的程序捕获了信号,并打印出类似的信息后退出:
正在休眠...
正在休眠...
正在休眠...
接收到中断信号 (2).
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 << "接收到中断信号 (" << signum << ").\n";
exit(signum);
}
int main () {
int i = 0;
signal(SIGINT, signalHandler);
while(++i) {
cout << "正在休眠...\n";
if( i == 3 ) {
raise( SIGINT);
}
sleep(1);
}
return 0;
}
当上述代码被编译和执行时,会产生如下结果,并自动退出:
正在休眠...
正在休眠...
正在休眠...
接收到中断信号 (2).