C++中的信号处理
在你的程序中会出现一些中断,这些中断被传递给在操作系统上运行的进程,并暂停运行的进程。这些中断被称为信号。在各种操作系统(Windows、Mac OS X、LINUX或UNIX)上按下Ctrl+C ,就可以产生一个示例信号。
在大多数情况下,这个组合键会发送一个中断信号。在我们进入C++的信号处理之前,你可能想了解一下编程语言的情况。
什么是C++编程语言?
C++是一种通用的跨平台编程计算机语言,它对大小写敏感,而且是自由格式。该语言具有高度的灵活性和可扩展性,使程序员对系统内存和资源有一个优化的控制水平。
它被用于开发操作系统(OS)、浏览器、应用程序、游戏、软件、图形用户界面(GUI)等。这种命令式和编译式语言是一个强大的框架,支持不同的编程方法,如面向对象的范式、函数式编程、通用编程和程序式编程。
C++中的信号处理
我们现在明白了,信号是一种中断,它使操作系统停止其任务,去关注另一个任务,为了停止这些任务,需要对信号进行处理。在C++中,信号是由语言提供的。
它可以捕捉到中断的信号,解决导致程序在执行任务时暂停的问题。下面是C++的信号库,开发人员可以处理的信号以及它们的操作。
信号操作
-
SIGINT(信号中断)--该信号用于在接收端产生一个交互式注意信号,作为 "程序中断"。当操作系统产生一个中断时,这个C++信号会停止中断并允许正在进行的任务继续进行。 -
SIGTERM(信号终止)- 这个信号由kill命令产生,用于向运行中的程序发送终止传入中断的请求。在传入的信号到达中断正在执行的任务之前就被杀死。 -
SIGBUS(信号总线)- 当有 的指示时,意味着有对无效地址的访问。这个信号通知正在进行的程序,有一个 ,获得了对无效地址的访问,程序被停止。BUS errorBUS error -
SIGILL(信号非法指令) - 这个信号用于检测非法的命令或指令,这可能是中断,并将其停止。 -
SIGALRM(信号报警) - 这个信号使用 功能,通过显示时间的到期来指示对无效地址的访问(中断)。alarm -
SIGSEGV(信号分段违反)-该信号显示并处理中断为无效访问的存储。 -
SIGHUP(信号挂起)--该信号用于向进程报告其控制终端已被中断终止的情况。 -
SIGQUIT(信号退出)- 这个信号产生一个核心转储,用来终止中断的产生。 -
SIGTRAP(signal trap) - 这个信号用于跟踪所有的陷阱(或异常),并向正在进行的进程发送关于它们的信息,请求终止。 -
SIGCONT(signal continue) - 这个信号被发送到正在进行的进程,使其在中断被阻止或终止后继续进行。 -
SIGSTOP(信号停止)--该信号自动终止并阻止进程中任何有可能出现的中断。
上面列出的信号可以捕获任何中断(或异常)并解决这些问题。
C++的signal()函数
C++信号()函数如何工作
C++signal() 函数遵循一连串的过程,其作用是带来预期的解决方案。首先要注意的是,在所有的信号函数中都有两个参数代表,这两个参数都起着至关重要的作用。
signal(registered signal, signal handler);
第一个参数,即registered signal 和整数,参与信号方法,第二个参数,即signal handler ,通过C++信号捕捉所有中断和异常。
当信号函数被编译时,它们将产生一个输出。这个输出将需要创建一个明显不同的中断,也就是说,捕捉中断时使用的信号将打印它们。
在这个过程之后,还包括另一个叫做raise function 的函数。这个函数考虑第一个参数,并向当前执行的程序发送定义的信号。提起一个函数就会产生必要的信号。
在这个过程中需要注意的信号函数包括。
原型(Prototypes)
这个信号函数定义在<csignal> 头文件中,描述了一种信号处理的方法。
通过该函数,处理程序可以被设置为执行以下动作之一。
- 通过默认方式处理信号。
- 通过忽略信号来处理信号。
- 通过一个用户定义的函数处理信号。
参数
这个信号函数由sig 和handler 组成。sig 是信号处理程序所处理的信号。
它可以是下面列表中提到的任何一个信号。
- 信号中止(SIGABRT)
- 信号浮点异常(SIGFPE)
- 信号非法指令(SIGILL)
- 信号中断(SIGINT)
- 信号终止(SIGTERM)等。
信号的形式应该是。void fun(int sig);
返回值
这是当输入的函数的请求成功与否的返回值。如果成功,它将返回到负责该命令的特定信号处理器。但如果不成功,则返回SIG_ERR 。
实施
下面的编译说明了使用SIGSEGV 方法时的信号处理过程的实现。
#include <csignal>
#include <iostream>
using namespace std;
sig_atomic_t sig_value = 0;
void s_handle(int signal_)
{
sig_value = signal_;
}
int main()
{
signal(SIGSEGV, s_handle);
cout << "Before the signal handler has been invoked " << sig_value << endl;
raise(SIGSEGV);
cout << "After the signal handler has been invoked " << sig_value << endl;
return 0;
}
一旦编译并执行,返回值将显示以下结果。
Before the signal handler has been invoked 0
After the signal handler has been invoked 11
结论
在这篇文章中,我们学习了如何在C++编程语言中处理信号。我们研究了信号操作以及如何实现它们。