详细分析C++ 信号处理

信号是由操作系统传给进程的中断,会提早终止一个程序。在 UNIX、LINUX、Mac OS X 或 Windows 系统上,可以通过按 Ctrl+C 产生中断。

有些信号不能被程序捕获,但是下表所列信号可以在程序中捕获,并可以基于信号采取适当的动作。这些信号是定义在 C++ 头文件 <csignal> 中。

信号 描述
SIGABRT 程序的异常终止,如调用 abort。
SIGFPE 错误的算术运算,比如除以零或导致溢出的操作。
SIGILL 检测非法指令。
SIGINT 程序终止(interrupt)信号。
SIGSEGV 非法访问内存。
SIGTERM 发送到程序的终止请求。

signal() 函数

C++ 信号处理库提供了 signal 函数,用来捕获突发事件。以下是 signal() 函数的语法:

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

这个函数接收两个参数:第一个参数是一个整数,代表了信号的编号;第二个参数是一个指向信号处理函数的指针。

让我们编写一个简单的 C++ 程序,使用 signal() 函数捕获 SIGINT 信号。不管您想在程序中捕获什么信号,您都必须使用 signal 函数来注册信号,并将其与信号处理程序相关联。看看下面的实例:

#include <iostream>
#include <csignal>
#include <unistd.h>

using namespace std;

void signalHandler( int signum )
{
  cout << "Interrupt signal (" << signum << ") received.\n";

  // 清理并关闭
  // 终止程序 

  exit(signum); 

}

int main ()
{
  // 注册信号 SIGINT 和信号处理程序
  signal(SIGINT, signalHandler); 

  while(1){
    cout << "Going to sleep...." << endl;
    sleep(1);
  }

  return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

Going to sleep....
Going to sleep....
Going to sleep....

现在,按 Ctrl+C 来中断程序,您会看到程序捕获信号,程序打印如下内容并退出:

Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.

raise() 函数

您可以使用函数 raise() 生成信号,该函数带有一个整数信号编号作为参数,语法如下:

int raise (signal sig);

在这里,sig 是要发送的信号的编号,这些信号包括:SIGINT、SIGABRT、SIGFPE、SIGILL、SIGSEGV、SIGTERM、SIGHUP。以下是我们使用 raise() 函数内部生成信号的实例:

#include <iostream>
#include <csignal>
#include <unistd.h>

using namespace std;

void signalHandler( int signum )
{
  cout << "Interrupt signal (" << signum << ") received.\n";

  // 清理并关闭
  // 终止程序 

  exit(signum); 

}

int main ()
{
  int i = 0;
  // 注册信号 SIGINT 和信号处理程序
  signal(SIGINT, signalHandler); 

  while(++i){
    cout << "Going to sleep...." << endl;
    if( i == 3 ){
     raise( SIGINT);
    }
    sleep(1);
  }

  return 0;
}

当上面的代码被编译和执行时,它会产生下列结果,并会自动退出:

Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.

以上就是详细分析C++ 信号处理的详细内容,更多关于C++ 信号处理的资料请关注我们其它相关文章!

(0)

相关推荐

  • python多线程下信号处理程序示例

    本文实例为大家分享了python多线程下信号处理程序示例的具体代码,供大家参考,具体内容如下 下面是一个网上转载的实现思路,经过验证,发现是可行的,就记录下来. 思路 python多线程中要响应Ctrl+C的信号以杀死整个进程,需要: 1.把所有子线程设为Daemon: 2.使用isAlive()函数判断所有子线程是否完成,而不是在主线程中用join()函数等待完成: 3.写一个响应Ctrl+C信号的函数,修改全局变量,使得各子线程能够检测到,并正常退出. 源码 #!/usr/bin/env p

  • PHP信号处理机制的操作代码讲解

    我们首先来看下实例代码: function sig_handler($sig) { print("handled sig: $sig\n"); } pcntl_signal(SIGIO, "sig_handler"); posix_kill(posix_getpid(),SIGIO); while(true) { posix_kill(posix_getpid(),SIGIO); pcntl_signal_dispatch(); sleep(1); } 最好自己手动

  • php 中的信号处理操作实例详解

    本文实例讲述了php 中的信号处理操作.分享给大家供大家参考,具体如下: 首先我们需要了解几个函数 pcntl_signal   安装信号处理器,也就是当指定信号发生时,调用函数. pcntl_alarm   指定秒数后向进程发送SIGALRM信号. posix_getpid 返回当前进程id posix_kill       给指定进程发送信号 一些常用的信号说明 SIGHUP 本信号在用户终端连接(正常或非正常)结束时发出, 通常是在终端的控制进程结束时, 通知同一session内的各个作业

  • Perl信号处理学习简单小结

    Unix 下常见的处理信号 复制代码 代码如下: No    Name         Default Action       Description  1     SIGHUP       terminate process    terminal line hangup  2     SIGINT       terminate process    interrupt program  3     SIGQUIT      create core image    quit progra

  • 对Python信号处理模块signal详解

    Python中对信号处理的模块主要是使用signal模块,但signal主要是针对Unix系统,所以在Windows平台上Python不能很好的发挥信号处理的功能. 要查看Python中的信号量,可以使用dir(signal)来查看. signal.signal() 在signal模块中,主要是使用signal.signal()函数来预设信号处理函数 singnal.signal(signalnum, handler) 其中第一个参数是信号量,第二个参数信号处理函数. 下面看个简单的例子,其中

  • Golang信号处理及如何实现进程的优雅退出详解

    Linux系统中的信号类型 各操作系统的信号定义或许有些不同.下面列出了POSIX中定义的信号. 在linux中使用34-64信号用作实时系统中. 命令 man 7 signal 提供了官方的信号介绍.也可以是用kill -l来快速查看 列表中,编号为1 ~ 31的信号为传统UNIX支持的信号,是不可靠信号(非实时的),编号为32 ~ 63的信号是后来扩充的,称做可靠信号(实时信号).不可靠信号和可靠信号的区别在于前者不支持排队,可能会造成信号丢失,而后者不会. Linux支持的标准信号有以下一

  • 详细分析C++ 信号处理

    信号是由操作系统传给进程的中断,会提早终止一个程序.在 UNIX.LINUX.Mac OS X 或 Windows 系统上,可以通过按 Ctrl+C 产生中断. 有些信号不能被程序捕获,但是下表所列信号可以在程序中捕获,并可以基于信号采取适当的动作.这些信号是定义在 C++ 头文件 <csignal> 中. 信号 描述 SIGABRT 程序的异常终止,如调用 abort. SIGFPE 错误的算术运算,比如除以零或导致溢出的操作. SIGILL 检测非法指令. SIGINT 程序终止(inte

  • 详细分析Redis集群故障

    故障表象: 业务层面显示提示查询redis失败 集群组成: 3主3从,每个节点的数据有8GB 机器分布: 在同一个机架中, xx.x.xxx.199 xx.x.xxx.200 xx.x.xxx.201 redis-server进程状态: 通过命令ps -eo pid,lstart | grep $pid, 发现进程已经持续运行了3个月 发生故障前集群的节点状态: xx.x.xxx.200:8371(bedab2c537fe94f8c0363ac4ae97d56832316e65) master

  • hibernate查询缓存详细分析

     一.查询缓存配置 1.在hibernate.cfg.xml中加入查询缓存的策略,  <propertyname="hibernate.cache.use_query_cache">true</property>      启用查询缓存的策略,默认是false. 二.关闭二级缓存,采用query.list()查询普通属性 代码如下所示. public voidtestCache1() { Session session = null; try { session

  • mysql中binlog_format模式与配置详细分析

    mysql复制主要有三种方式:基于SQL语句的复制(statement-based replication, SBR),基于行的复制(row-based replication, RBR),混合模式复制(mixed-based replication, MBR).对应的,binlog的格式也有三种:STATEMENT,ROW,MIXED. ① STATEMENT模式(SBR) 每一条会修改数据的sql语句会记录到binlog中.优点是并不需要记录每一条sql语句和每一行的数据变化,减少了binl

  • Android编程之微信SDK分享功能过程步骤详细分析

    本文实例讲述了Android编程之微信SDK分享功能过程步骤详细分析.分享给大家供大家参考,具体如下: 之前已经分析过怎么用官方的demo分享微信信息了,在这里我就不再多说,其中关于在自己应用分享说得很简单,本文作者也是经过一番折腾才弄成功,为了以后让大家都少走弯路,决定在这里从头到尾介绍怎么在自己的应用中分享功能 注意:顺序不能乱!! 1.建立自己的应用 TestShareWX (1)应用包名是com.freeson.test,然后建立一个测试Activity,名字为TestActivity,

  • 详细分析Android中onTouch事件传递机制

    onTach介绍 ontach是Android系统中整个事件机制的基础.Android中的其他事件,如onClick.onLongClick等都是以onTach为基础的. onTach包括从手指按下到离开手机屏幕的整个过程,在微观形式上,具体表现为action_down.action_move和action_up等过程. onTach两种主要定义形式如下: 1.在自定义控件中,常见的有重写onTouchEvent(MotionEvent ev)方法.如在开发中经常可以看到重写的onTouchEv

  • 详细分析jsonp的原理和实现方式

    针对跨域问题,本文主要给大家详细分析一下jsonp的原理,希望能够给你提供到帮助. 详细分析jsonp的原理和实现方式 一:跨域问题. 二,跨域产生的原因 Js是不能跨域请求.出于安全考虑,js设计时不可以跨域. 什么是跨域: 1.域名不同时. 2.域名相同,端口不同. 只有域名相同.端口相同时,才可以访问. 可以使用jsonp解决跨域问题. 三,跨域失败的案例 3.1,同源策略 首先基于安全的原因,浏览器是存在同源策略这个机制的,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档

  • python的变量与赋值详细分析

    python的变量与赋值 1.变量的命名规则 变量其实通过一个标记调用内存中的值,而变量名就是这个标记的名称,但是万一这个标记已经被提前占用或者解释器认为这个标记是不合法的,那么就会报错.下面总结了一下变量的命名规则: 1.不能使用python的关键字,也就是说标记不能被提前占用,python的关键字包括: ['and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', '

  • 基于Java 生产者消费者模式(详细分析)

    生产者消费者模式是多线程中最为常见的模式:生产者线程(一个或多个)生成面包放进篮子里(集合或数组),同时,消费者线程(一个或多个)从篮子里(集合或数组)取出面包消耗.虽然它们任务不同,但处理的资源是相同的,这体现的是一种线程间通信方式. 本文将先说明单生产者单消费者的情况,之后再说明多生产者多消费者模式的情况.还会分别使用wait()/nofity()/nofityAll()机制.lock()/unlock()机制实现这两种模式. 在开始介绍模式之前,先解释下wait().notify()和no

  • 详细分析sqlserver中的小数类型(float和decimal)

    在SQL Server中实际上只有两种小数数值类型,分别是float(近似数值)和decimal(精确数值),这两种类型能表示所有的小数数值类型. float(近似数值类型) float表示的是近似数值,存在一定的精度缺失. float(n) 这里的n是以科学计数法存储浮点数尾数的位数,因此此参数决定了精度和存储的大小.其是可选的,默认值是53,即float等价于float(53),占用8bytes.如果指定了n,则它必须是介于1至53之间的值.实际上,虽然n的取值范围定义是1至53,但实际上f

随机推荐