C++ 信号处理

C++ 信号处理 首页 / C++入门教程 / C++ 信号处理
  • 信号是由操作系统传递给进程的中断,以停止正在进行的任务并参加为其生成中断的任务。
  • 信号也可以由操作系统根据系统或错误情况生成。
  • 您可以通过在Linux上按 Linux上的Ctrl + C 来生成中断。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++ 信号处理库提供函数信号以捕获意外中断或事件。

void (*signal (int sig, void (*func)(int)))(int);

参数

设置此函数以处理信号。

它指定一种处理 sig 指定的信号编号的方法。

参数 func 指定程序可以处理信号的三种方式之一。

  • 默认处理(SIG_DFL)  -  由该特定信号的默认操作处理的信号。
  • 忽略信号(SIG_IGN)   -  即使无意,该信号也将被忽略并且代码将继续执行。
  • 函数处理程序                 -  已定义一个特定的函数来处理信号。

我们必须记住,我们要捕获的信号必须使用信号函数进行注册,并且必须与信号处理函数相关联。

Note: 信号处理功能应为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;
}

输出:

Signal is handled

例子2

让我们看另一个简单的例子:

#include <csignal>
#include <iostream>
 
namespace
{
  volatile std::sig_atomic_t gSignalStatus;
}
 
void signal_handler(int signal)
{
  gSignalStatus = signal;
}
 
int main()
{
 //安装信号处理程序
  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> 头文件声明函数raise()以处理特定信号。

int raise (int sig);

参数

信号:要发送以进行处理的信号号。它可以采用以下值之一:

  • 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

祝学习愉快!(内容编辑有误?请选中要编辑内容 -> 右键 -> 修改 -> 提交!)

技术教程推荐

Nginx核心知识150讲 -〔陶辉〕

Vue开发实战 -〔唐金州〕

雷蓓蓓的项目管理实战课 -〔雷蓓蓓〕

Kafka核心源码解读 -〔胡夕〕

互联网人的英语私教课 -〔陈亦峰〕

分布式数据库30讲 -〔王磊〕

手机摄影 -〔@随你们去〕

攻克视频技术 -〔李江〕

程序员职业规划手册 -〔雪梅〕

好记忆不如烂笔头。留下您的足迹吧 :)