C++ 信号处理


C++信号处理机制是Linux操作系统的重要特性之一,它可以在不同进程之间实现信号的传递,使得进程可以快速、有效地响应处理特定的事件或异常情况。本文主要介绍C++信号处理的基本概念、信号的种类以及如何编写信号处理程序。

一、信号处理机制的基本概念

  1. 信号定义:信号是指一个软件中断,用来通知进程发生了某个特定的事件。Linux中有多个不同的信号,每个信号都有一个唯一的编号,我们可以通过编号或名称来引用信号。

  2. 信号产生:信号通常分为两种类型:一种是由系统产生的信号,一种是由用户进程产生的信号。

    系统产生的信号包括以下几种情况:

    SIGINT:终端输入信号(CTRL+C),通常用于中断正在运行的进程。

    SIGKILL:结束进程,无法被屏蔽,无法捕捉。

    SIGTERM:终止信号,可以被屏蔽,允许进程处理后终止。

    SIGALRM:定时器信号,用于定时响应某些事件。

    SIGSEGV:进程访问了一个非法地址,会导致进程崩溃。

    SIGPIPE:进程向一个已经关闭的管道或socket连接发送数据,会产生此信号。

    用户产生的信号通常通过调用 kill() 函数实现,可以将信号发送给另一个进程,也可以发送给当前进程(比如自身)。

  3. 信号处理函数:一旦进程收到一个信号,就会执行相应的信号处理程序。 Linux提供了 sigaction() 函数,可以为每种类型的信号指定一个处理程序,以响应相应的事件。

二、信号的种类

Linux提供了多种类型的信号,不同的信号使用不同的编号,其含义和处理方式也不同。常见的信号类型包括以下几种:

  1. SIGHUP:连接挂断信号。

  2. SIGINT:终止进程信号。

  3. SIGQUIT:生成core文件,停止进程信号。

  4. SIGKILL:无法忽略的终止进程信号。

  5. SIGALRM:定时器信号。

  6. SIGTERM:发送给进程的终止信号。

  7. SIGCHLD:子进程状态变更信号。

  8. SIGPIPE:管道破裂信号。

  9. SIGUSR1和SIGUSR2:用户定义信号。

三、编写信号处理程序

C ++使用 signal() 函数注册信号处理程序,当系统收到某个信号时,就会调用相应的信号处理程序。

下面是一个处理 SIGINT 信号的示例程序:

#include<signal.h> #include<stdlib.h> #include<stdio.h> void InteruptSignalHandler(int signum){ printf(“当前进程 %d 收到信号 %d”, getpid(), signum); exit(1); } int main(){ signal(SIGINT, InteruptSignalHandler); //注册信号处理程序 while(1) { printf(“正在运行…\n”); sleep(1); } }

在此示例程序中,我们定义了一个新的函数 InteruptSignalHandler(),用于处理由系统发送的 SIGINT 信号。当进程收到 SIGINT 信号时,系统会调用 InteruptSignalHandler() 函数,该函数会输出当前进程的进程 ID 和接收到的信号编号,然后退出程序。

在 main() 函数中,通过调用 signal() 函数将SIGINT信号与 InteruptSignalHandler() 函数关联起来,以便系统在接到SIGINT信号时调用该函数。此后,我们定义了一个无限循环,程序一直运行着,直到接收到 SIGINT 信号。

四、总结

本文介绍了C++中信号处理机制的基本概念、信号的种类以及如何编写信号处理程序。了解这些知识可以帮助我们更好地掌握和利用信号处理特性,有效地响应进程产生的事件或异常情况。