C++ 信号处理
信号是由操作系统传递给进程的中断,以停止正在进行的任务并参加为其生成中断的任务。
信号也可以由操作系统根据系统或错误情况生成。
您可以通过在 C 来生成中断.lidihuo.com/linux-tutorial"> Linux ,UNIX,Mac OS X或Windows系统。
有些信号不能被程序捕获,但是下面列出了一些信号,您可以在程序中捕获它们,并可以根据信号采取适当的措施。
这些信号在<csingnal>头文件中定义。
以下是信号列表以及它们的描述和工作能力:
信号 |
说明 |
SIGABRT |
(信号中止)程序异常终止,例如调用中止。 |
SIGFPE |
(信号浮点异常)错误的算术运算,例如被零除或导致溢出的运算。 |
SIGILL |
(信号非法指令),用于检测非法指令。 |
SIGINT |
(信号中断),用于接收交互式程序中断信号。 |
SIGSEGV |
(违反信号分割)对存储的无效访问。 |
SIGTERM |
(信号终止)发送到程序的终止请求。 |
SIGHUP |
(信号挂断)挂断(POSIX),它报告用户终端断开连接。用于报告控制过程的终止。 |
SIGQUIT |
用于终止进程并生成核心转储。 |
SIGTRAP |
跟踪陷阱。 |
SIGBUS |
这是BUS错误,表明访问了无效地址。 |
SIGUSR1 |
用户定义的信号1、 |
SIGUSR2 |
用户定义的信号2、 |
SIGALRM |
闹钟,指示访问无效地址。 |
SIGTERM |
用于终止。该信号可以被阻止,处理和忽略。由kill命令生成。 |
SIGCOUNT |
此信号发送到进程以使其继续。 |
SIGSTOP |
停止,不可阻挡。该信号用于停止进程。无法处理,忽略或阻止此信号。 |
signal()函数
C++ signal-处理库提供函数信号以捕获意外中断或事件。
语法
void (*signal (int sig, void (*func)(int)))(int);
参数
此功能设置为处理信号。
它指定一种处理由 指定的信号编号的方法。 sig 。
参数 func 指定程序可以处理信号的三种方式之一。
默认处理(SIG_DFL): 由该特定信号的默认操作处理的信号。
忽略信号(SIG_IGN): 即使无意,该信号也将被忽略并且代码将继续执行。
函数处理程序: 定义了一个特定的函数来处理信号。
我们必须记住,我们要捕获的信号必须使用信号功能进行注册,并且必须与信号处理功能相关联。
注意: 信号处理功能应为void类型。
返回值
此函数的返回类型与参数func的类型相同。
如果成功请求此函数后,该函数将返回指向特定处理程序函数的指针,该函数负责在调用之前处理此信号。
数据争用
数据竞赛未定义。如果在多线程程序中调用此函数,则会导致未定义的行为。
异常
此函数绝不会引发异常。
示例1
让我们看一个简单的示例来演示signal()函数的使用:
#include <iostream>
#include <csignal>
using namespace std;
sig_atomic_t signalled = 0;
void handler(int sig)
{
signalled = 1;
}
int main()
{
signal(SIGINT, handler);
raise(SIGINT);
if (signalled)
cout << "Signal is handled";
else
cout << "Signal is not handled";
return 0;
}
输出:
示例2
让我们看另一个简单的示例:
#include <csignal>
#include <iostream>
namespace
{
volatile std::sig_atomic_t gSignalStatus;
}
void signal_handler(int signal)
{
gSignalStatus = signal;
}
int main()
{
// Install a signal handler
std::signal(SIGINT, signal_handler);
std::cout << "SignalValue: " << gSignalStatus << '\n';
std::cout << "Sending signal " << SIGint << '\n';
std::raise(SIGINT);
std::cout << "SignalValue: " << gSignalStatus << '\n';
}
输出:
SignalValue: 0
Sending signal 2
SignalValue: 2
raise()函数
C++信号raise()函数用于将信号发送到当前正在执行的程序。
<csignal> 头文件声明了函数handle()以处理特定信号。
语法
参数
信号: 要发送以进行处理的信号号。它可以采用以下值之一:
SIGINT
SIGABRT
SIGFPE
SIGILL
SIGSEGV
SIGTERM
SIGHUP
返回值
成功则返回0,失败则返回非零。
数据争用
同时调用此函数是安全的,不会引起数据争用。
异常
如果未使用信号定义函数处理程序来处理引发的信号,则此函数永远不会引发异常。
示例1
让我们看一个简单的示例来说明在传递SIGABRT时使用raise()函数:
#include <iostream>
#include <csignal>
using namespace std;
sig_atomic_t sig_value = 0;
void handler(int sig)
{
sig_value = sig;
}
int main()
{
signal(SIGABRT, handler);
cout << "Before signal handler is called" << endl;
cout << "Signal = " << sig_value << endl;
raise(SIGABRT);
cout << "After signal handler is called" << endl;
cout << "Signal = " << sig_value << endl;
return 0;
}
输出:
Before signal handler is called
Signal = 0
After signal handler is called
Signal = 6
示例2
让我们看一个简单的示例,以说明在传递SIGINT时对raise()函数的使用:
#include <csignal>
#include <iostream>
using namespace std;
sig_atomic_t s_value = 0;
void handle(int signal_)
{
s_value = signal_;
}
int main()
{
signal(SIGINT, handle);
cout << "Before called Signal = " << s_value << endl;
raise(SIGINT);
cout << "After called Signal = " << s_value << endl;
return 0;
}
输出:
Before called Signal = 0
After called Signal = 2
示例3
让我们看一个简单的示例,以说明在传递SIGTERM时对raise()函数的使用:
#include <csignal>
#include <iostream>
using namespace std;
sig_atomic_t s_value = 0;
void handle(int signal_)
{
s_value = signal_;
}
int main()
{
signal(SIGTERM, handle);
cout << "Before called Signal = " << s_value << endl;
raise(SIGTERM);
cout << "After called Signal = " << s_value << endl;
return 0;
}
输出:
Before called Signal = 0
After called Signal = 15
示例4
让我们看一个简单的示例,以说明在传递SIGSEGV时对raise()函数的使用:
#include <csignal>
#include <iostream>
using namespace std;
sig_atomic_t s_value = 0;
void handle(int signal_)
{
s_value = signal_;
}
int main()
{
signal(SIGSEGV, handle);
cout << "Before called Signal = " << s_value << endl;
raise(SIGSEGV);
cout << "After called Signal = " << s_value << endl;
return 0;
}
输出:
Before called Signal = 0
After called Signal = 11
示例5
让我们看一个简单的示例来说明在传递SIGFPE时使用raise()函数:
#include <csignal>
#include <iostream>
using namespace std;
sig_atomic_t s_value = 0;
void handle(int signal_)
{
s_value = signal_;
}
int main()
{
signal(SIGFPE, handle);
cout << "Before called Signal = " << s_value << endl;
raise(SIGFPE);
cout << "After called Signal = " << s_value << endl;
return 0;
}
输出:
Before called Signal = 0
After called Signal = 8